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