Error executing template "Designs/Tefcold/eCom/ProductCatalog/basic_Pim.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at Tefcold.Web.CustomCode.Razor.ProductViewModelExtensions.GetSpecifications(ProductViewModel product)
at Tefcold.Web.CustomCode.Extensions.ProductExtensions.GetAsseccoriesList(ProductViewModel viewModel, String shopId)
at CompiledRazorTemplates.Dynamic.RazorEngine_689d7817b0224f0595a2ef01f7a72b9d.Execute() in E:\Solutions\Live\Tefcold.Web\Files\Templates\Designs\Tefcold\eCom\ProductCatalog\basic_Pim.cshtml:line 35
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.Platforms.Dynamicweb9.Specs
3 @using NLWI.Core.Factory
4 @using System.Linq;
5 @using System.Text.RegularExpressions
6 @using Dynamicweb.Ecommerce.International
7 @using Dynamicweb.Ecommerce.ProductCatalog
8 @using Dynamicweb.Ecommerce.Products
9 @using Dynamicweb.Ecommerce.Stocks
10 @using Dynamicweb.Security.UserManagement
11 @using NORRIQ.Common8.Ecom
12 @using Newtonsoft.Json
13 @using Newtonsoft.Json.Serialization
14 @using NORRIQ.SalesPersonLogin.Services
15 @using NORRIQ.Seo.Canonical
16 @using Tefcold.Web.CustomCode.AsyncProductList.Models
17 @using Tefcold.Web.CustomCode.Extensions
18 @using Tefcold.Web.CustomCode.Items
19 @using Tefcold.Web.CustomCode.Items.Properties
20 @using Tefcold.Web.CustomCode.Items.Settings
21 @*@using Tefcold.Web.CustomCode.ProductHelper*@
22 @using Tefcold.Web.CustomCode.Razor
23 @using Tefcold.Web.CustomCode.Stocks
24 @using Tefcold.Web.CustomCode.Stocks.Helpers
25 @inherits Tefcold.Web.CustomCode.Razor.TefcoldViewModelTemplate<Dynamicweb.Ecommerce.ProductCatalog.ProductViewModel>
26 @{
27 var websiteSettings = Pageview.Area.Item.ToCodeFirstItem<Websites>();// Dynamicweb.Services.Items.GetItem(Pageview.Area.ItemType, Pageview.Area.ItemId).ToCodeFirstItem<Websites>();
28
29 var stockInformation = StockLocationHelper.GetShopStockInformation(Pageview.ID);
30
31 //Dynamicweb.Ecommerce.Services.StockService.GetStockUnits("34024-at-SHOP2", "");
32 //var stockInformation = StockLocationHelper.GetShopStockInformation(Pageview.ID);
33 var variantId = System.Web.HttpContext.Current.Request.QueryString["VariantID"];
34 var selectedModel = (!string.IsNullOrEmpty(variantId) ? Model.Variants?.FirstOrDefault(a => string.Equals(a.VariantId, variantId)) : null) ?? Model;
35 var accessories = selectedModel.GetAsseccoriesList(Pageview.Area.EcomShopId);
36 var relatedProducts = Model.GetProductRelationGroup("Related Products");// Configuration
37 var perfionImageNames = new string[] { "PrimaryImage", "DetailImage1", "DetailImage2", "BrandedImage", "PackedImage", "OtherImages", "WithContentImage", "OpenImage", "ImageRange", "ImageOnLocation","StorageImages" };
38 //var specsToList = new HashSet<string>() { "Fitting", "Features", "USP", "Gender", "Season", "Year" }; @*Leave empty for all *@
39
40 var remoteStock = StockUnitHelper.GetRemoteStock(selectedModel, Pageview, websiteSettings.ExternalShopIds);
41
42 var inspirationGroupIds = websiteSettings.InspirationGroupIds ?? new List<string>();
43 selectedModel.StockUnits = selectedModel.StockUnits.GetShopStocks(Pageview.Area.EcomShopId).ToList();
44
45
46 string youtubeID = selectedModel.GetSpecifications().GetByKey("YouTubeURL").Value;
47
48 var convertedSelectedModel = new AsyncProductWithSpecification(new SimpleProduct(selectedModel, null, stockInformation, inspirationGroupIds, websiteSettings.ExternalShopIds, true));
49 convertedSelectedModel.Product.DefaultPrice.CurrencyCode = Pageview.Area.EcomCurrencyId;
50 var convertedMasterModel = new AsyncProductWithSpecification(new SimpleProduct(Model, null, stockInformation, inspirationGroupIds, websiteSettings.ExternalShopIds, true));
51
52 var selectedJsonModel = JsonConvert.SerializeObject(convertedSelectedModel, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
53 var selectedMasterProductModel = JsonConvert.SerializeObject(convertedMasterModel, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
54 selectedMasterProductModel = selectedMasterProductModel.Replace("'", "'");
55 selectedJsonModel = selectedJsonModel.Replace("'", "'");
56
57 string asyncPrefix = "Async ";
58 var userInTefcoldUserGroup = ImpersonationService.IsCurrentlyImpersonating();
59 FieldValueViewModel isSpareField;
60 selectedModel.ProductFields.TryGetValue("IsSparePart", out isSpareField);
61 var isSparePart = (bool)isSpareField.Value;
62
63 var product = Dynamicweb.Ecommerce.Services.Products.GetProductById(Model.Id, Model.VariantId, Model.LanguageId);
64
65 var productIsBlocked = product != null && !product.Active;
66
67 //Used to determine whether or not to show phdCode
68
69 if (isSparePart)
70 {
71
72 Pageview.Meta.AddTag("robots", "noindex,nofollow");
73 }
74
75 // Specs
76 var specs = ProductViewModelExtensions.GetSpecifications(selectedModel);
77 var images = perfionImageNames.SelectMany(a => specs.GetAllByKey(a)).ToList();
78 var imageAlt = specs.GetByKey("ProductName");
79
80 var ecoIcon = specs.GetByKey("EcoIcon");
81
82 var trueString = true.ToString().ToLower();
83
84 string basicPimPrefix = "PDP ";
85 var languageId = Model.LanguageId;
86
87 var productService = ObjectFactory.GetInstance<ProductService>();
88 LanguageService languageService = new LanguageService();
89 //ProductFields
90
91 DateTime result;
92 string earliestHarborArrival = selectedModel.ProductFields.FirstOrDefault(f => f.Value.SystemName == "EarliestArrivalFromHarbor").Value?.Value?.ToString() ?? string.Empty;
93
94 if (DateTime.TryParseExact(earliestHarborArrival, "yyyy-mm-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
95 {
96 var earliestArrivalTranslateString = Translate(basicPimPrefix + "stock arriving soon. Due", "Stock arriving soon. Due");
97 earliestHarborArrival = result.ToString("dd/mm/yyyy");
98 earliestHarborArrival = earliestArrivalTranslateString + " " + earliestHarborArrival;
99 }
100
101 //websiteSettings = Pageview.GetWebsiteSettings();
102 string shortSellingText = specs.GetByKey("SellingTextShort")?.Value;
103 string energyArrow = specs.GetByKey("EnergyArrow")?.Value;
104 string energyLabel = specs.GetByKey("EnergyLabel")?.Value;
105 var marketingMessage = specs.GetByKey("MarketingMessage")?.Value;
106
107 var stickerImage = Model.GetStickerImage();
108 string netVolumeEnergyRating = specs.GetByKey("NetVolumeEnergyRating")?.Value;
109 string totalDisplayArea = specs.GetByKey("TotalDisplayArea")?.Value;
110 var standardCustomer = Pageview.AreaSettings.GetString("StandardCustomer");
111 standardCustomer = string.IsNullOrEmpty(standardCustomer) ? "" : standardCustomer;
112 string detailImage1Text = specs.GetByKey("DetailImage1Text")?.Value;
113 string detailImage2Text = specs.GetByKey("DetailImage2Text")?.Value;
114 }
115 <product-details-simple-pim :product='@selectedJsonModel'
116 :images='@Newtonsoft.Json.JsonConvert.SerializeObject(images.Select(a => a.Value))'
117 inline-template
118 language-id="@Model.LanguageId">
119 <div class="basic_pim" v-bind:class="{'initialized': initialized }">
120 <section class="basic_pim-pdp" itemscope="" itemtype="https://schema.org/Product">
121 <div class="basic_pim-media">
122 <div class="@(images.Count() > 1 ? "basic_pim-pictos thumbs" : "basic_pim-pictos")">
123 <div class="stickers">
124 @if (!string.IsNullOrEmpty(stickerImage))
125 {
126 <img src="/Admin/Public/GetImage.ashx?Height=@TefcoldParagraphSettings.StickHeightDetails&Compression=85&Image=@stickerImage" alt="@Translate(basicPimPrefix + "Sticker", "Sticker")" class="img-fluid"/>
127 }
128 @if (websiteSettings.DiscountFormat != null)
129 {
130 <span v-if="ShowDiscount" class="sticker discount">
131 -{{discount}}%
132 </span>
133 }
134
135 </div>
136 @if (!string.IsNullOrEmpty(ecoIcon?.Value))
137 {
138 <img src="@(ecoIcon?.Value)" alt="@Translate(basicPimPrefix + "eco product", "Eco product")" class="img-fluid" style="margin-left:auto;" />
139 }
140
141 </div>
142 <gallery :items="images"
143 :index="index"
144 @@close="index = null">
145 </gallery>
146 <template v-if="images.length > 1">
147 <slick ref="slick"
148 class="basic_pim-thumbs"
149 id="pdp-thumbs"
150 :options="slickPimOptionsThumbs">
151 <figure v-for="thumb in images" class="basic_pim-thumb">
152 <img :src="'/Admin/Public/GetImage.ashx?Width=50&Height=50&Compression=85&Crop=5&Format=webp&Quality=85&fillcanvas=True&Image=' + thumb"
153 alt="@selectedModel.Name"
154 class="img-fluid" />
155 </figure>
156 @if (!string.IsNullOrEmpty(youtubeID))
157 {
158 <figure class="basic_pim-thumb">
159 <svg x="0px" y="0px"
160 width="48" height="48"
161 viewBox="0 0 48 48">
162 <path fill="#FF3D00" d="M43.2,33.9c-0.4,2.1-2.1,3.7-4.2,4c-3.3,0.5-8.8,1.1-15,1.1c-6.1,0-11.6-0.6-15-1.1c-2.1-0.3-3.8-1.9-4.2-4C4.4,31.6,4,28.2,4,24c0-4.2,0.4-7.6,0.8-9.9c0.4-2.1,2.1-3.7,4.2-4C12.3,9.6,17.8,9,24,9c6.2,0,11.6,0.6,15,1.1c2.1,0.3,3.8,1.9,4.2,4c0.4,2.3,0.9,5.7,0.9,9.9C44,28.2,43.6,31.6,43.2,33.9z"></path>
163 <path fill="#FFF" d="M20 31L20 17 32 24z"></path>
164 </svg>
165 </figure>
166 }
167
168 </slick>
169 <slick ref="slick"
170 class="basic_pim-images"
171 id="pdp-images"
172 :options="slickPimOptionsImages">
173 <figure class="basic_pim-image"
174 v-for="(image, imageIndex) in images"
175 :key="imageIndex"
176 @@click="setIndex(imageIndex)"
177 title="@Translate(basicPimPrefix + "show image", "Show image")">
178 <picture>
179 <source media="(max-width:767.98px)" :srcset="'/Admin/Public/GetImage.ashx?Width=400&Height=400&Compression=85&Crop=5&Format=webp&Quality=85&fillcanvas=True&Image=' + image">
180 <source media="(max-width:991.98px)" :srcset="'/Admin/Public/GetImage.ashx?Width=530&Height=530&Compression=85&Crop=5&Format=webp&Quality=85&fillcanvas=True&Image=' + image">
181 <img :src="'/Admin/Public/GetImage.ashx?Width=530&Height=530&Compression=85&Crop=5&Format=webp&Quality=85&fillcanvas=True&Image=' + image"
182 alt="@selectedModel.Name"
183 class="img-fluid"
184 itemprop="image" />
185 </picture>
186 @if (!string.IsNullOrEmpty(detailImage1Text) || !string.IsNullOrEmpty(detailImage2Text))
187 {
188 <figcaption class="alert bg-white" v-if="imageIndex < 3">
189 @if (!string.IsNullOrEmpty(detailImage1Text))
190 {
191 <template v-if="imageIndex == 1">
192 @detailImage1Text
193 </template>
194 }
195 @if (!string.IsNullOrEmpty(detailImage2Text))
196 {
197 <template v-if="imageIndex == 2">
198 @detailImage2Text
199 </template>
200 }
201 </figcaption>
202 }
203 </figure>
204 @if (!string.IsNullOrEmpty(youtubeID))
205 {
206 <figure :key="images.Count"
207 @@click="setIndex(images.Count)"
208 title="@Translate(basicPimPrefix + "show image", "Show image")">
209 <div>
210 <youtube-embed-lite vid="@youtubeID" thumb-quality="hq" class="embed-responsive-item" />
211 </div>
212 </figure>
213 }
214
215
216 </slick>
217 </template>
218 <template v-if="images.length == 1">
219 <div class="basic_pim-images">
220 <figure class="basic_pim-image"
221 v-for="(image, imageIndex) in images"
222 :key="imageIndex"
223 @@click="setIndex(imageIndex)"
224 title="@Translate(basicPimPrefix + "show image", "Show image")">
225 <picture>
226 <source media="(max-width:767.98px)" :srcset="'/Admin/Public/GetImage.ashx?Width=300&Height=250&Compression=85&Crop=5&Format=webp&Quality=85&fillcanvas=True&Image=' + image">
227 <source media="(max-width:991.98px)" :srcset="'/Admin/Public/GetImage.ashx?Width=400&Height=350&Compression=85&Crop=5&Format=webp&Quality=85&fillcanvas=True&Image=' + image">
228 <img :src="'/Admin/Public/GetImage.ashx?Width=427&Height=427&Compression=85&Crop=5&Format=webp&Quality=85&fillcanvas=True&Image=' + image"
229 alt="@selectedModel.Name"
230 class="img-fluid"
231 itemprop="image">
232 </picture>
233 @if (!string.IsNullOrEmpty(detailImage1Text) || !string.IsNullOrEmpty(detailImage2Text))
234 {
235 <figcaption class="alert bg-white">
236 @if (!string.IsNullOrEmpty(detailImage1Text))
237 {
238 <template v-if="imageIndex == 1">
239 @detailImage1Text
240 </template>
241 }
242 @if (!string.IsNullOrEmpty(detailImage2Text))
243 {
244 <template v-if="imageIndex == 2">
245 @detailImage2Text
246 </template>
247 }
248 </figcaption>
249 }
250 </figure>
251 </div>
252 </template>
253 <template v-if="images.length == 0">
254 @{
255 var pdpImage = "/Files/Images/default.jpg";
256 }
257 <div class="basic_pim-image">
258 <picture class="basic_pim-image">
259 <source media="(max-width:1199.98px)" srcset="/Admin/Public/GetImage.ashx?Width=630&Height=630&Compression=85&Crop=5&Format=webp&Quality=85&Image=@(pdpImage)">
260 <source media="(max-width:991.98px)" srcset="/Admin/Public/GetImage.ashx?Width=530&Height=530&Compression=85&Crop=5&Format=webp&Quality=85&Image=@(pdpImage)">
261 <source media="(max-width:767.98px)" srcset="/Admin/Public/GetImage.ashx?Width=400&Height=400&Compression=85&Crop=5&Format=webp&Quality=85&Image=@(pdpImage)">
262 <img src="@(pdpImage)"
263 alt="@Translate(basicPimPrefix + "No product picture", "No product picture")"
264 class="img-fluid"
265 itemprop="image">
266 </picture>
267 </div>
268 </template>
269 </div>
270 <div class="basic_pim-content">
271 <header>
272 <h1 itemprop="name">
273 @selectedModel.Name
274 </h1>
275 <p itemprop="category">@(selectedModel?.ShortDescription ?? "")</p>
276 </header>
277 @if (specs.GetAllByKey("BulletPoints").Any())
278 {
279 <ul class="basic_pim-specs">
280 @foreach (var bp in specs.GetAllByKey("BulletPoints"))
281 {
282 <li>
283 @bp.Value
284 </li>
285 }
286 </ul>
287 }
288
289 @*
290 <template name="item-stock-state" v-if="stockLocationState!=0">
291 <p :class="'stock out-of-stock'" v-if="stockLocationState==5">
292 <link itemprop="availability" href="http://schema.org/SoldOut" />
293 @Translate(asyncPrefix + "Out Of Stock", "Out Of Stock")
294 </p>
295 <p :class="'stock few-in-stock'" v-if="stockLocationState==7">
296 <link itemprop="availability" href="http://schema.org/LimitedAvailability" />
297 @Translate(asyncPrefix + "Few In Stock", "Few In Stock")
298 </p>
299 <p :class="'stock in-stock'" v-if="stockLocationState==8">
300 <link itemprop="availability" href="http://schema.org/InStock" />
301 @Translate(asyncPrefix + "In Stock", "In Stock")
302 </p>
303 </template>
304 *@
305
306 @if (!string.IsNullOrEmpty(marketingMessage) && Pageview.IsCurrentlyB2B())
307 {
308 <span class="basic_pim-marketing-message">@marketingMessage</span>
309 }
310
311 @if (Pageview.IsAllowedToShop() && !productIsBlocked)
312 {
313 <stock-location-component inline-template :remote-stock-shop-ids='@JsonConvert.SerializeObject(websiteSettings.ExternalShopIds)' not-in-stock-text="@Translate(basicPimPrefix + "not in stock text", "N/A")" :default-stock-units='product.product.stockUnits' :default-remote-stock-units='@Newtonsoft.Json.JsonConvert.SerializeObject(remoteStock)' :product='product' earliest-harbor-arrival-date="@earliestHarborArrival">
314 <div class="basic_pim-stocks">
315 <template v-if="stockUnits.length > 0 && !loading">
316 <div v-for="unit in stockUnits" class="custom-control custom-radio">
317 <span style="font-size: 1px">{{unit.quantity}}</span>
318 <input type="radio" v-model="selectedVal" name="stocks" :id="unit.stockLocation.name" :value="unit.stockLocation.name" class="custom-control-input" :disabled="unit.quantity <=0 || getStockLocation!=''" :checked="getStockLocation == unit.stockLocation.name">
319 <label v-if="!@userInTefcoldUserGroup.ToString().ToLower()" :for="unit.stockLocation.name" class="custom-control-label">
320 {{ unit.stockLocation.description }} {{ GetStockAmountString(unit.quantity) }} @Translate("PDP In Stock", "In Stock")
321 <template v-if="stocksHasNoQuantity">
322 <br/><span style="font-size: small;">{{earliestHarborArrivalDate}}</span>
323 </template>
324 </label>
325 <label v-else :for="unit.stockLocation.name" class="custom-control-label">
326 {{ unit.stockLocation.description }} {{ unit.quantity }} @Translate("PDP In Stock", "In Stock")
327 <template v-if="stocksHasNoQuantity">
328 <br/><span style="font-size: small;">{{earliestHarborArrivalDate}}</span>
329 </template>
330 </label>
331 </div>
332 <br/>
333 </template>
334 <template v-else-if="loading">
335 <span class="spinner-sm-default"></span>
336 </template>
337 <template v-if="remoteStockUnits.length > 0 && !loading">
338 <div v-for="unit in remoteStockUnits" class="custom-control ">
339 <span style="font-size: 1px">{{unit.Quantity}}</span>
340 @*<input type="radio" v-model="selectedVal" name="stocks" :id="unit.StockLocation.Description" :value="unit.StockLocation.Description" class="custom-control-input" :disabled="true">*@
341 @*<label v-if="!@userInTefcoldUserGroup.ToString().ToLower()" :for="unit.StockLocation.Description" class="custom-control-label">{{ unit.StockLocation.Description }} {{ GetStockAmountString(unit.Quantity) }} @Translate("PDP In Stock", "In Stock")</label>*@
342 <label v-if="!@userInTefcoldUserGroup.ToString().ToLower()" :for="unit.StockLocation.Description" class="">
343 {{ unit.StockLocation.Description }} {{ GetStockAmountString(unit.Quantity) }} @Translate("PDP In Stock", "In Stock")
344 <br /><span style="font-size: small;">@Translate("Back In Stock Again Text", "Stock due on")</span>
345 </label>
346 <label v-else :for="unit.StockLocation.Description" class="custom-control">
347 {{ unit.StockLocation.Description }} {{ unit.Quantity }} @Translate("PDP In Stock", "In Stock")
348 <br/><span style="font-size: small;">@Translate("Back In Stock Again Text", "Stock due on")</span>
349 </label>
350
351 </div>
352 </template>
353 </div>
354 </stock-location-component>
355 }
356 @if (!Pageview.IsAllowedToShop() || productIsBlocked)
357 {
358 <buying-component inline-template :initial-product='@selectedMasterProductModel' :selected-product='@selectedMasterProductModel'>
359 <div class="basic_pim-buying">
360
361 @if (!string.IsNullOrEmpty(energyArrow))
362 {
363 string name = Regex.Replace(selectedModel.Name.Trim(), "[^A-Za-z0-9_. ]+", "");
364 //var lang = languageService.GetLanguage(selectedModel.LanguageId)?.Code2;
365
366 //string filePattern = $"[[type]]-{selectedModel.Number}-{name}-{lang}";
367 <div class="pdp-energy">
368 <div class="pdp-energy-data">
369 <a href="@energyLabel" target="_blank" class="pdp-energy-label">
370 <img src="/Admin/Public/GetImage.ashx?Height=40&Crop=5&Image=@energyArrow" />
371 </a>
372 <a href="#" v-on:click="getProductReport($event,'@selectedModel.Number', '@name','@selectedModel.LanguageId')" target="_blank" class="pdp-energy-link">
373
374 @Translate(basicPimPrefix + "product sheet", "Product Sheet")
375
376 </a>
377 </div>
378 </div>
379 }
380
381 <ul class="basic_pim-variants" v-if="initialProduct.product.simpleVariants && initialProduct.product.simpleVariants.length > 0">
382 <li>
383 @{
384 FieldValueViewModel productImg;
385 FieldValueViewModel productColor;
386 Model.ProductFields.TryGetValue("productVariantColorImage", out productImg);
387 Model.ProductFields.TryGetValue("productVariantValue", out productColor);
388 }
389 <a href="Default.aspx?ID=@Pageview.ID&ProductId=@Model.Id" class="@(Model.Number == selectedModel.Number ? "active" : "")" :style="getImageOrColor('@(productImg?.Value)','@(productColor?.Value)')"></a>
390 </li>
391
392 @if (Model.Variants != null)
393 {
394 foreach (var variant in Model.Variants)
395 {
396 FieldValueViewModel variantImg;
397 FieldValueViewModel variantColor;
398 variant.ProductFields.TryGetValue("productVariantColorImage", out variantImg);
399 variant.ProductFields.TryGetValue("productVariantValue", out variantColor);
400
401 <li>
402 <a href="/Default.aspx?ID=@Pageview.ID&ProductId=@variant.Id&VariantId=@variant.VariantId" class="@(variant.Number == selectedModel.Number ? "active" : "")" :style="getImageOrColor('@(variantImg?.Value)','@(variantColor?.Value)')"></a>
403 </li>
404
405 }
406 }
407 </ul>
408 </div>
409 </buying-component>
410 <p itemprop="sku">
411 @Translate(basicPimPrefix + "Product number", "Product number"): @selectedModel.Number @(string.IsNullOrEmpty(selectedModel.GetNavItemNumber()) ? "" : "("+Translate("Substition for","Substitution for ")+ $"{selectedModel.GetNavItemNumber()})")
412 </p>
413 <a href="@NORRIQ.Common8.Razor.Navigation.GetUrlByNavigationTag("contact")" class="btn btn-outline-secondary btn-sm mt-3">
414 @Translate("create account", "Create account")
415 </a>
416 }
417 else
418 {
419 <buying-component inline-template @@discount="onDiscount($event)" :initial-product='@selectedMasterProductModel' :selected-product='@selectedMasterProductModel' :chosen-warranty-code="chosenWarrantyCode" :warranty-info="warrantyInfo">
420 <div class="basic_pim-buying" itemprop="offers" itemscope="" itemtype="https://schema.org/Offer">
421 <div class="pdp-energy">
422 <async-price class-type="asyncprice-pdp"
423 :product='@selectedJsonModel'
424 :default-price="@selectedModel.Price.PriceWithoutVat.ToString(CultureInfo.InvariantCulture)"
425 :only-standard-price="@(Pageview.IsCurrentlyB2C().ToString().ToLower())"
426 list-price="true"
427 :should-emit-warranties="true"
428 language-id="@languageId"
429 standard-customer="@standardCustomer"
430 @@discount="onDiscount($event)">
431 </async-price>
432 @if (!string.IsNullOrEmpty(energyArrow))
433 {
434 string name = Regex.Replace(selectedModel.Name.Trim(), "[^A-Za-z0-9_. ]+", "");
435 //var lang = languageService.GetLanguage(selectedModel.LanguageId)?.Code2;
436
437 //string filePattern = $"[[type]]-{selectedModel.Number}-{name}-{lang}";
438 <div class="pdp-energy-data">
439 <a href="@energyLabel" target="_blank" class="pdp-energy-label">
440 <img src="/Admin/Public/GetImage.ashx?Height=40&Crop=5&Image=@energyArrow" />
441 </a>
442 <a href="#" v-on:click="getProductReport($event,'@selectedModel.Number', '@name','@selectedModel.LanguageId')" target="_blank" class="pdp-energy-link">
443
444 @Translate(basicPimPrefix + "product sheet", "Product Sheet")
445
446 </a>
447 </div>
448 }
449 </div>
450 <ul class="basic_pim-variants" v-if="initialProduct.product.simpleVariants && initialProduct.product.simpleVariants.length > 0">
451 <li>
452 @{
453 FieldValueViewModel productImg;
454 FieldValueViewModel productColor;
455 Model.ProductFields.TryGetValue("productVariantColorImage", out productImg);
456 Model.ProductFields.TryGetValue("productVariantValue", out productColor);
457 }
458 <a href="Default.aspx?ID=@Pageview.ID&ProductId=@Model.Id" class="@(Model.Number == selectedModel.Number ? "active" : "")" :style="getImageOrColor('@(productImg?.Value)','@(productColor?.Value)')"></a>
459 </li>
460
461 @if (Model.Variants != null)
462 {
463 foreach (var variant in Model.Variants)
464 {
465 FieldValueViewModel variantImg;
466 FieldValueViewModel variantColor;
467 variant.ProductFields.TryGetValue("productVariantColorImage", out variantImg);
468 variant.ProductFields.TryGetValue("productVariantValue", out variantColor);
469
470 <li>
471 <a href="/Default.aspx?ID=@Pageview.ID&ProductId=@variant.Id&VariantId=@variant.VariantId" class="@(variant.Number == selectedModel.Number ? "active" : "")" :style="getImageOrColor('@(variantImg?.Value)','@(variantColor?.Value)')"></a>
472 </li>
473
474 }
475 }
476 </ul>
477 <div class="pdp-btn-group">
478 <add-to-basket-simple class="addtobasketsimple-pdp"
479 :product='@selectedJsonModel'
480 :price-without-vat="currentItemPriceWithoutVat"
481 button-class="btn btn-primary"
482 :group-warranty-code="chosenWarrantyCode"
483 :warranty-info="warrantyInfo"
484 :unit-of-measure="'PCS'"
485 language-id="@languageId"
486 :only-spare-parts="@((Pageview.User.OnlySpareParts() && !isSparePart).ToString().ToLower())"
487 :is-marketing-user="@(Pageview.User.OnlyView().ToString().ToLower())"
488 :ishvasuser="@(Pageview.User.IsHVACUser().ToString().ToLower())"
489 standard-customer="@standardCustomer">
490 </add-to-basket-simple>
491 @if (Pageview.IsCurrentlyB2B())
492 {
493 <favorite-lists ui-error-message-translation="@Translate(basicPimPrefix + " Error while retrieving favorite list", "Error while retrieving favorite list")" :is-favorite-mode="@NORRIQ.Common8.Razor.Navigation.GetPageIdByNavigationTag("favorites") == @Pageview.ID" :product='@selectedJsonModel'></favorite-lists>
494 }
495 <add-to-compare :product-number="selectedProduct.product.number"></add-to-compare>
496 </div>
497 </div>
498 </buying-component>
499 <p itemprop="sku">
500 @Translate(basicPimPrefix + "Product number", "Product number"): @selectedModel.Number @(string.IsNullOrEmpty(selectedModel.GetNavItemNumber()) ? "" : "(" + Translate("Substition for", "Substitution for ") + $"{selectedModel.GetNavItemNumber()})")
501
502 </p>
503 if (Pageview.IsCZShop() && !string.IsNullOrEmpty(specs.GetByKey("PhdCode")?.Value))
504 {
505 <p class="phdCode">@Translate(basicPimPrefix + "PhdCode", "PhdCode") @(specs.GetByKey("PhdCode")?.Value)</p>
506 }
507 if (!isSparePart && (Pageview.IsCurrentlyB2B() && Pageview.User.AllowWarranty() || Pageview.IsCurrentlyB2C()))
508 {
509 <div class="basic_pim-warranty" v-if="@((!isSparePart).ToString().ToLower()) && warranties?.length>0">
510 <div v-for="(warranty,index) in warranties" class="custom-control custom-radio">
511 <input type="radio" name="warranty" :id="'warranty' + index" v-model="chosenWarranty" :value="warranty" class="custom-control-input" />
512 <label :for="'warranty' + index" class="custom-control-label">
513 {{getDescription(warranty.itemNo) +' - ' + product.product.defaultPrice.currencyCode + ' ' + warranty.price.priceWithoutVat + ',-'}}
514 </label>
515 </div>
516 @*<template v-if="warrantyLoading">
517 <div class="basic_listview-loader text-center">http://localhost:55277/http://localhost:55277/
518 <span class="spinner-lg-default"></span>
519 </div>
520 </template>*@
521 </div>
522 }
523 }
524 @if (isSparePart && specs.GetByGroup("NIQSpecifications").Any())
525 {
526 <ul class="list-unstyled spare-specs mt-3">
527 @foreach (var group in specs.GetByGroup("NIQSpecifications").Where(x => x.Key != "EcoIcon").OrderBy(x => x.Group2Order).ThenBy(x => x.ValueSortOrder).GroupBy(x => x.Group2))
528 {
529
530
531 foreach (var spec in group)
532 {
533
534 <li>
535
536 <span>@spec.Caption</span>
537 <span>
538 @spec.Value
539 @spec.Unit
540 </span>
541 </li>
542 }
543
544 }
545 </ul>
546 }
547 </div>
548 </section>
549 @if (!isSparePart)
550 {
551 <section class="basic_pim-collapse">
552 @if (!string.IsNullOrEmpty(selectedModel.LongDescription) || !string.IsNullOrEmpty(shortSellingText) || specs.GetByGroup("NIQSpecifications").Any())
553 {
554 <div class="basic_pim-col" visible id="specs1">
555 @if (!string.IsNullOrEmpty(selectedModel.LongDescription) || !string.IsNullOrEmpty(shortSellingText))
556 {
557 <button class="btn-collapse" id="description" v-b-toggle.long-description>
558 @Translate(basicPimPrefix + "product description", "Product description")
559 </button>
560 <b-collapse id="long-description" appear accordion="specs1">
561 <template>
562 <div class="body-collapse">
563 @if (!string.IsNullOrEmpty(shortSellingText))
564 {
565 <p>@shortSellingText</p>
566 }
567 @if (!string.IsNullOrEmpty(selectedModel.LongDescription))
568 {
569 <p>@selectedModel.LongDescription</p>
570 }
571 </div>
572 </template>
573 </b-collapse>
574 }
575 @if (specs.GetByGroup("NIQSpecifications").Any())
576 {
577 <button class="btn-collapse" id="specs" v-b-toggle.specs-list>
578 @Translate(basicPimPrefix + "Product Specs", "Product Specifications")
579 </button>
580 <b-collapse id="specs-list" accordion="specs1">
581 <template>
582 <div class="body-collapse full">
583 <table class="table table-specs">
584
585 <tbody>
586
587 @foreach (var group in specs.GetByGroup("NIQSpecifications").Where(x => x.Key != "EcoIcon").OrderBy(x => x.Group2Order).ThenBy(x => x.ValueSortOrder).GroupBy(x => x.Group2))
588 {
589 var test = specs;
590
591 <tr>
592 <th>@group.Key</th>
593 <th></th>
594 </tr>
595 foreach (var spec in group)
596 {
597 if (spec.Key == "EnergyArrow")
598 {
599 continue;
600 }
601 if (spec.Key == "EnergyArrowText" && !string.IsNullOrEmpty(energyArrow))
602 {
603 <tr>
604 <td>
605 @spec.Caption
606 </td>
607 <td valign="middle" style="vertical-align:middle;">
608 <a href="@energyLabel" target="_blank" style="display:flex;">
609 <img src="/Admin/Public/GetImage.ashx?Height=18&Crop=5&Image=@energyArrow" />
610 </a>
611 </td>
612 </tr>
613 }
614 else
615 {
616 <tr>
617 <td>
618 @spec.Caption
619 </td>
620 <td valign="middle" style="vertical-align:middle;">
621 @spec.Value
622 @spec.Unit
623 </td>
624 </tr>
625 }
626 }
627 }
628 <tr>
629 <th></th>
630 <th></th>
631 </tr>
632 </tbody>
633 </table>
634
635 </div>
636 </template>
637 </b-collapse>
638 }
639 </div>
640 }
641 <div class="basic_pim-col" id="specs2">
642
643 <button class="btn-collapse" id="download" v-b-toggle.download-documents>
644 @Translate(basicPimPrefix + "downloads", "Downloads")
645 </button>
646 <b-collapse id="download-documents" accordion="specs2">
647 <template>
648 <div class="body-collapse">
649 <ul class="basic_pim-downloads">
650 @{
651
652 string name = Regex.Replace(selectedModel.Name.Trim(), "[^A-Za-z0-9_. ]+", "");
653 var lang = languageService.GetLanguage(selectedModel.LanguageId)?.Code2;
654
655 }
656 @{ string filePattern = $"[[type]]-{selectedModel.Number}-{name}-{lang}"; }
657 <li>
658 <a href="#" v-on:click="getProductReport($event,'@selectedModel.Number', '@name','@lang')" target="_blank">
659 <svg>
660 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
661 </svg>
662 @Translate(basicPimPrefix + "product sheet", "Product Sheet")
663 </a>
664 </li>
665 @if (!string.IsNullOrEmpty(@specs.GetByKey("Usermanual").Value))
666 {
667 <li>
668 <a href="#" v-on:click="downloadProductFile($event,'@name','@specs.GetByKey("Usermanual").Value','@filePattern.Replace("[[type]]", "Usermanual")','Usermanual')" target="_blank">
669 <svg>
670 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
671 </svg>
672 @Translate(basicPimPrefix + "User manual", "User manual")
673 </a>
674 </li>
675 }
676 @if (!string.IsNullOrEmpty(@specs.GetByKey("SparePartsBC").Value))
677 {
678 <li>
679 <a href="#" v-on:click="downloadProductFile($event,'@name','@specs.GetByKey("SparePartsBC").Value','@filePattern.Replace("[[type]]","SparePartsBC")','SparePartsBC')" target="_blank">
680 <svg>
681 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
682 </svg>
683 @Translate(basicPimPrefix + basicPimPrefix + "spare part list", "Spare part list")
684 </a>
685 </li>
686 }
687 @if (!string.IsNullOrEmpty(energyLabel))
688 {
689 <li>
690 <a href="#" v-on:click="downloadProductFile($event,'@name','@energyLabel','@filePattern.Replace("[[type]]","EnergyClassification")','EnergyClassification')" target="_blank">
691 <svg>
692 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
693 </svg>
694 @Translate(basicPimPrefix + "Energy Classification", "Energy Classification")
695 </a>
696 </li>
697 }
698 @if (Pageview.User != null && Pageview.User.AllowDownloadDocuments())
699 {
700 if (!string.IsNullOrEmpty(specs.GetByKey("WiringDiagrams").Value))
701 {
702 <li>
703 <a href="#" v-on:click="downloadProductFile($event,'@name','@specs.GetByKey("WiringDiagrams").Value','@filePattern.Replace("[[type]]","WiringDiagrams")','WiringDiagrams')" target="_blank">
704 <svg>
705 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
706 </svg>
707 @Translate(basicPimPrefix + "Wiring diagram", "Wiring diagram")
708 </a>
709 </li>
710 }
711 if (!string.IsNullOrEmpty(specs.GetByKey("Drawings").Value))
712 {
713 <li>
714 <a href="#" v-on:click="downloadProductFile($event,'@name','@specs.GetByKey("Drawings").Value','@filePattern.Replace("[[type]]","Drawings")','Drawings')" target="_blank">
715 <svg>
716 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
717 </svg>
718 @Translate(basicPimPrefix + "Drawings", "Drawings")
719 </a>
720 </li>
721 }
722 if (!string.IsNullOrEmpty(specs.GetByKey("BrandingFile").Value))
723 {
724 <li>
725 <a href="#" v-on:click="downloadProductFile($event,'@name','@specs.GetByKey("BrandingFile").Value','@filePattern.Replace("[[type]]","Branding")','BrandingFile')" target="_blank">
726 <svg>
727 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
728 </svg>
729 @Translate(basicPimPrefix + "Branding File", "Branding drawing")
730 </a>
731 </li>
732 }
733 if (!string.IsNullOrEmpty(specs.GetByKey("QuickGuide").Value))
734 {
735 <li>
736 <a href="#" v-on:click="downloadProductFile($event,'@name','@specs.GetByKey("QuickGuide").Value','@filePattern.Replace("[[type]]","QuickGuide")','QuickGuide')" target="_blank">
737 <svg>
738 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
739 </svg>
740 @Translate(basicPimPrefix + "QuickGuide", "Quick Guide")
741 </a>
742 </li>
743 }
744 if (!string.IsNullOrEmpty(specs.GetByKey("AssemblyGuide").Value))
745 {
746 <li>
747 <a href="#" v-on:click="downloadProductFile($event,'@name','@specs.GetByKey("AssemblyGuide").Value','@filePattern.Replace("[[type]]","AssemblyGuide")','AssemblyGuide')" target="_blank">
748 <svg>
749 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#download"></use>
750 </svg>
751 @Translate(basicPimPrefix + "AssemblyGuide", "Assembly Guide")
752 </a>
753 </li>
754 }
755 }
756 </ul>
757 </div>
758
759 </template>
760 </b-collapse>
761
762 @if (!isSparePart)
763 {
764 <product-spare-parts-view :page-view-id="@Pageview.ID"
765 :language-id="'@selectedModel.LanguageId'"
766 :product-number="@selectedModel.Number"
767 :exploded-drawing="'@(specs.GetByKey("ExplodedDrawing")?.Value)'"
768 :spare-part-report="'@(specs.GetByKey("SparePartsBC").Value)'"
769 product-name="@name"
770 language-code="@lang"
771 :sparepart-location="product.product.defaultStockLocationName">
772 </product-spare-parts-view>
773 }
774
775 </div>
776 </section>
777 }
778 @if (accessories != null && accessories.Any())
779 {
780
781 <section class="basic_related">
782 <template>
783 <header class="basic_related-header" id="accessories-header">
784 <h2 class="text-center">
785 @Translate(basicPimPrefix + "Accessories", "Accessories")
786 </h2>
787 </header>
788 <slick ref="slick"
789 class="basic_related-grid"
790 :options="slickAccessoriesOptions">
791 @foreach (var accessory in accessories)
792 {
793 var converted = new AsyncProductWithSpecification(new SimpleProduct(accessory.ToViewModel(), null, stockInformation, inspirationGroupIds, websiteSettings.ExternalShopIds, true));
794 var accessoryJson = JsonConvert.SerializeObject(converted, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
795 accessoryJson = accessoryJson.Replace("'", "'");
796 <article class="basic_related-product">
797 <a href="/Default.aspx?ID=@NORRIQ.Common8.Razor.Navigation.GetPageIdByNavigationTag("plp")&ProductID=@accessory.Id" class="basic_related-url">
798 <figure>
799 @{
800 var image = string.IsNullOrEmpty(accessory.ImageLarge) ? "/Files/Images/default.jpg" : "/Files/" + accessory.ImageLarge;
801 }
802 <img src="/Admin/Public/GetImage.ashx?Width=427&Height=427&Compression=85&Crop=5&Image=@image"
803 alt="@accessory.Name"
804 class="img-fluid" />
805 </figure>
806 <header>
807 <h1>@accessory.Name</h1>
808 <p class="basic_related-category">@accessory.ShortDescription</p>
809 <p class="basic_related-sku">@Translate(basicPimPrefix + "Product Number", "Product Number") @accessory.Number</p>
810 </header>
811 </a>
812 @if (Pageview.IsCurrentlyB2B())
813 {
814 <buying-component inline-template :initial-product='@accessoryJson'>
815 <footer>
816 <async-price class-type="asyncprice-plp"
817 :default-price="@accessory.Price.PriceWithoutVAT.ToString(CultureInfo.InvariantCulture)"
818 :product='@accessoryJson'
819 only-price="true"
820 standard-customer="@standardCustomer">
821 </async-price>
822 <add-to-basket-simple :product='@accessoryJson'
823 button-class="btn btn-primary"
824 class="addtobasketsimple-plp ml-auto"
825 language-id="@languageId"
826 :price-without-vat="@accessory.Price.PriceWithoutVAT.ToString(CultureInfo.InvariantCulture)"
827 :only-spare-parts="@((Pageview.User.OnlySpareParts() && !isSparePart).ToString().ToLower())"
828 :is-marketing-user="@(Pageview.User.OnlyView().ToString().ToLower())"
829 :ishvasuser="@(Pageview.User.IsHVACUser().ToString().ToLower())"
830 standard-customer="@standardCustomer">
831 </add-to-basket-simple>
832 </footer>
833 </buying-component>
834
835 }
836 else
837 {
838 <footer>
839 <async-price class-type="asyncprice-plp"
840 :default-price="@accessory.Price.PriceWithoutVAT.ToString(CultureInfo.InvariantCulture)"
841 :product='@accessoryJson'
842 only-price="true"
843 :only-standard-price="@(Pageview.IsCurrentlyB2C().ToString().ToLower())"
844 standard-customer="@standardCustomer" />
845
846 <div class="asyncprice-plp">
847 <div class="price-withoutvat">
848 <span class="price-label">@Translate(basicPimPrefix + "price without vat", "Price without VAT")</span>
849 <p class="price">
850 <span class="unit-price">
851 @accessory.Price.PriceWithoutVATFormattedNoSymbol @accessory.Price.Currency.Code
852 </span>
853 </p>
854 </div>
855 </div>
856 <add-to-basket-simple :product='@accessoryJson'
857 button-class="btn btn-primary"
858 class="addtobasketsimple-plp ml-auto"
859 language-id="@languageId"
860 :price-without-vat="@accessory.Price.PriceWithoutVAT.ToString(CultureInfo.InvariantCulture)"
861 :only-spare-parts="@((Pageview.User.OnlySpareParts() && !isSparePart).ToString().ToLower())"
862 :is-marketing-user="@(Pageview.User.OnlyView().ToString().ToLower())"
863 :ishvasuser="@(Pageview.User.IsHVACUser().ToString().ToLower())"
864 standard-customer="@standardCustomer">
865 </add-to-basket-simple>
866 </footer>
867 }
868 </article>
869 }
870 </slick>
871 </template>
872 </section>
873 }
874 @if (relatedProducts != null && relatedProducts.RelatedProducts.Any())
875 {
876 <section class="basic_related">
877 <template>
878 <header class="basic_related-header" id="related-header">
879 <h2 class="text-center">
880 @Translate(basicPimPrefix + "Related Products", "Related Products")
881 </h2>
882 </header>
883 <slick ref="slick"
884 class="basic_related-grid"
885 :options="slickRelatedOptions">
886 @foreach (var relProduct in relatedProducts.RelatedProducts)
887 {
888
889 //var relProduct = productService.GetProductById(rel.Id, rel.VariantId, rel.LanguageId);
890 var converted = new AsyncProductWithSpecification(new SimpleProduct(relProduct.ToViewModel(), null, stockInformation, inspirationGroupIds, websiteSettings.ExternalShopIds, true));
891 var relProductJson = JsonConvert.SerializeObject(converted, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
892 relProductJson = relProductJson.Replace("'", "'");
893 <article class="basic_related-product">
894 <a href="/Default.aspx?ID=@NORRIQ.Common8.Razor.Navigation.GetPageIdByNavigationTag("plp")&ProductID=@relProduct.Id" class="basic_related-url">
895 <figure style="min-height: 1px;">
896 @{
897 var image = string.IsNullOrEmpty(relProduct.ImageLarge) ? "/Files/Images/default.jpg" : "/Files/" + relProduct.ImageLarge;
898 }
899 <img src="/Admin/Public/GetImage.ashx?Width=427&Height=427&Compression=85&Crop=5&fillcanvas=true&Image=@image"
900 alt="@relProduct.Name"
901 class="img-fluid" />
902 </figure>
903 <header>
904 <h1>@relProduct.Name</h1>
905 <p class="basic_related-category">@relProduct.ShortDescription</p>
906 <p class="basic_related-sku">@Translate(basicPimPrefix + "Product Number", "Product Number") @relProduct.Number</p>
907 </header>
908 </a>
909
910 @if (Pageview.IsCurrentlyB2B())
911 {
912
913 <buying-component @@discount="onDiscount($event)" inline-template :initial-product='@relProductJson' :selected-product='@relProductJson'>
914 <footer>
915 <async-price class-type="asyncprice-plp"
916 :default-price="@relProduct.Price.PriceWithoutVAT.ToString(CultureInfo.InvariantCulture)"
917 :product='@relProductJson'
918 unit-of-measure="PCS"
919 only-price="true"
920 should-emit-warranties="true"
921 :only-standard-price="@(Pageview.IsCurrentlyB2C().ToString().ToLower())"
922 standard-customer="@standardCustomer"
923 @@discount="onDiscount($event)">
924 </async-price>
925 <add-to-basket-simple :product='@relProductJson'
926 button-class="btn btn-primary"
927 :unit-of-measure="'PCS'"
928 class="addtobasketsimple-plp ml-auto"
929 :price-without-vat="currentItemPriceWithoutVat"
930 language-id="@languageId"
931 :only-spare-parts="@((Pageview.User.OnlySpareParts() && !isSparePart).ToString().ToLower())"
932 :is-marketing-user="@(Pageview.User.OnlyView().ToString().ToLower())"
933 :ishvasuser="@(Pageview.User.IsHVACUser().ToString().ToLower())"
934 standard-customer="@standardCustomer"
935 @@discount="onDiscount($event)">
936 </add-to-basket-simple>
937 </footer>
938 </buying-component>
939
940 }
941 else
942 {
943 <footer>
944 <async-price class-type="asyncprice-plp"
945 :default-price="@relProduct.Price.PriceWithoutVAT.ToString(CultureInfo.InvariantCulture)"
946 :product='@relProductJson'
947 only-price="true"
948 :only-standard-price="@(Pageview.IsCurrentlyB2C().ToString().ToLower())"
949 standard-customer="@standardCustomer" />
950
951 <add-to-basket-simple :product='@relProductJson'
952 :unit-of-measure="'PCS'"
953 button-class="btn btn-primary"
954 class="addtobasketsimple-plp ml-auto"
955 language-id="@languageId"
956 :price-without-vat="@relProduct.Price.PriceWithoutVAT.ToString(CultureInfo.InvariantCulture)"
957 :only-spare-parts="@((Pageview.User.OnlySpareParts() && !isSparePart).ToString().ToLower())"
958 :is-marketing-user="@(Pageview.User.OnlyView().ToString().ToLower())"
959 :ishvasuser="@(Pageview.User.IsHVACUser().ToString().ToLower())"
960 standard-customer="@standardCustomer">
961 </add-to-basket-simple>
962 </footer>
963 }
964 </article>
965 }
966 </slick>
967 </template>
968 </section>
969 }
970
971 </div>
972 </product-details-simple-pim>
973