Error executing template "Designs/Swift_custom/Paragraph/Swift_ProductPrice.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_071638b8a1f941da96c86ab1732e278e.Execute() in D:\dynamicweb.net\Solutions\Capo\sundqvist-new.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift_custom\Paragraph\Swift_ProductPrice.cshtml:line 49
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.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
2 @using Dynamicweb.Ecommerce.ProductCatalog
3 @using Newtonsoft.Json;
4 @using Newtonsoft.Json.Linq;
5 @using System.Globalization
6 @using Dynamicweb.Ecommerce.Products;
7 @using Dynamicweb.DataIntegration.Integration.ERPIntegration;
8 <style>
9 .campaign-price {
10 color: #e32477;
11 }
12 .item_swift_productprice{
13 margin-bottom: -7px;
14 }
15 </style>
16 17 @{
18 ProductViewModel product = new ProductViewModel();
19 20 21 22 ProductViewModelSettings productSetting = new ProductViewModelSettings
23 {
24 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID,
25 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code,
26 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2,
27 ShopId = Pageview.Area.EcomShopId,
28 29 };
30 31 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
32 {
33 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
34 }
35 else if (Pageview.Item["DummyProduct"] != null)
36 {
37 38 string dummyProductId = "";
39 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
40 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
41 if (productList.Products != null)
42 {
43 foreach (var p in productList.Products) { dummyProductId = p.Id; }
44 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel();
45 product = dummyProduct;
46 }
47 else
48 {
49 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id);
50 }
51 }
52 else if (Pageview.Item["DummyProduct"] == null)
53 {
54 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id);
55 }
56 57 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", "");
58 bool anonymousUser = Pageview.User == null;
59 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); ;
60 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown;
61 62 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice");
63 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty;
64 65 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2");
66 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", "");
67 string layout = Model.Item.GetRawValueString("Layout", "horizontal");
68 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty;
69 textAlign = horizontalAlign == "end" ? "text-end" : textAlign;
70 71 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign;
72 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign;
73 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign;
74 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign;
75 76 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column";
77 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty;
78 string order = layout == "horizontal" ? string.Empty : "order-2";
79 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
80 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme;
81 82 string contentPadding = Model.Item.GetRawValueString("ContentPadding", "");
83 contentPadding = contentPadding == "none" ? "p-0" : contentPadding;
84 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding;
85 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding;
86 87 }
88 89 @if (!hidePrice && product.Id != null)
90 {
91 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower();
92 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat);
93 94 string priceMin = "";
95 string priceMax = "";
96 97 string liveInfoClass = "";
98 string productInfoFeed = "";
99 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]);
100 bool isCampaign = Dynamicweb.Core.Converter.ToBoolean(product.ProductFields["productCampaign"].Value);
101 bool isOutlet = Dynamicweb.Core.Converter.ToBoolean(product.ProductFields["productOutlet"].Value);
102 bool isDisableAddtoCart = Pageview.AreaSettings.GetBoolean("DisableAddToCart");
103 if (isLazyLoadingForProductInfoEnabled)
104 {
105 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
106 {
107 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
108 if (!string.IsNullOrEmpty(productInfoFeed))
109 {
110 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
111 }
112 }
113 liveInfoClass = "js-live-info";
114 }
115116 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" @productInfoFeed>
117 @if (showInformativePrice && product.PriceInformative.Price != 0)
118 {
119 <div class="opacity-50">
120121 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span>
122 </div>
123 }
124 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign" itemprop="offers" itemscope itemtype="https://schema.org/Offer">
125 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
126127128 @if (showPricesWithVat == "false" && !neverShowVat)
129 {
130131 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
132 {
133 <span itemprop="price" content="" class="d-none"></span>
134 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span>
135 }
136 else
137 {
138 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted;
139140 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span>
141 if (product.Price.Price != product.PriceBeforeDiscount.Price)
142 {
143 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span>
144 }
145 }
146 }
147 else
148 {
149 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
150 {
151 <span itemprop="price" content="" class="d-none"></span>
152 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span>
153 }
154 else
155 {
156157 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted;
158159 <span itemprop="price" content="@product.Price.Price" class="d-none"></span>
160161 if (product.Price.Price != product.PriceBeforeDiscount.Price)
162 {
163 <span class="text-decoration-line-through opacity-75 @order">
164 <span class="text-price">@beforePrice</span>
165 </span>
166167 }
168 }
169 }
170171 @if (showPricesWithVat == "false" && !neverShowVat)
172 {
173 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
174 {
175 <span class="text-price js-text-price">
176 <span class="spinner-border" role="status"></span>
177 </span>
178 }
179 else
180 {
181 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted;
182183 if (product?.VariantInfo?.VariantInfo != null)
184 {
185 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : "";
186 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : "";
187 }
188 if (priceMin != priceMax)
189 {
190 price = priceMin + " - " + priceMax;
191 }
192193 if (Model.PageID == GetPageIdByNavigationTag("ProductDetailsComponent"))
194 {
195 <div>
196 <span class="fs-3 mb-1"><b>@price</b></span>
197 </div>
198 }
199 }
200 }
201 else
202 {
203 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
204 {
205 <span class="text-price js-text-price">
206 <span class="spinner-border" role="status"></span>
207 </span>
208 }
209 else
210 {
211 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted;
212213 if (anonymousUser)
214 {
215 // Actual system price just visually remove 00 decimals if the price is already round
216 price = product.Price.PriceWithVatFormatted.Replace(",00", "");
217 // Perform rounding of anonymous prices that are not rounded - with custom formatting function
218 //price = App_Code.Capo_Helpers.FormatStringPriceIncExTax(product.Price.PriceWithoutVat.ToString(), true);
219220 }
221222 if (product?.VariantInfo?.VariantInfo != null)
223 {
224 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : "";
225 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : "";
226 }
227 if (priceMin != priceMax)
228 {
229 price = priceMin + " - " + priceMax;
230 }
231232 if (isCampaign && Model.PageID == GetPageIdByNavigationTag("ProductDetailsComponent") && !isDisableAddtoCart || isOutlet && Model.PageID == GetPageIdByNavigationTag("ProductDetailsComponent") && !isDisableAddtoCart)
233 {
234 if (anonymousUser)
235 {
236 string productPriceConsumerOld = string.Empty;
237 productPriceConsumerOld = Dynamicweb.Core.Converter.ToString(product.ProductFields["productPriceOld"].Value);
238 string productPriceConsumerOldFormatted = App_Code.Capo_Helpers.FormatStringPriceIncExTax(productPriceConsumerOld, true);
239240 <span class="@theme @contentPadding" >
241 <span class="text-price campaign-price fs-3"><b>@price </b></span>
242 <span class="text-price text-decoration-line-through"><b>@productPriceConsumerOldFormatted</b></span>
243 </span>
244 }
245 else
246 {
247 <span class="@theme @contentPadding">
248 <span class="text-price campaign-price fs-3">@price</span>
249 </span>
250 }
251 }
252 else
253 {
254 if (anonymousUser)
255 {
256 //Slider
257 if (isCampaign && !isDisableAddtoCart || isOutlet && !isDisableAddtoCart)
258 {
259 string productPriceConsumerOld = string.Empty;
260 productPriceConsumerOld = Dynamicweb.Core.Converter.ToString(product.ProductFields["productPriceOld"].Value);
261 string productPriceConsumerOldFormatted = App_Code.Capo_Helpers.FormatStringPriceIncExTax(productPriceConsumerOld, true);
262263 <span class="@theme @contentPadding" >
264 <span class="text-price campaign-price fs-3"><b>@price </b></span><br>
265 <span class="text-price text-decoration-line-through"><b>@productPriceConsumerOldFormatted</b></span>
266 </span>
267 }
268 else
269 {
270 <span class="@theme @contentPadding">
271 <span class="text-price fs-3"><b>@price</b></span>
272 </span>
273 }
274 }
275 }
276 }
277 }
278279 @* Stock state for Schema.org, start *@
280 @{
281 Uri url = Dynamicweb.Context.Current.Request.Url;
282 }
283284 <link itemprop="url" href="@url">
285286 @{
287 bool IsNeverOutOfStock = product.NeverOutOfstock;
288 }
289290 @if (IsNeverOutOfStock)
291 {
292 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span>
293 }
294 else
295 {
296 if (product.StockLevel > 0)
297 {
298 <span itemprop="availability" class="d-none">InStock</span>
299 }
300 else
301 {
302 <span itemprop="availability" class="d-none">OutOfStock</span>
303 }
304 }
305 @* Stock state for Schema.org, stop *@
306307 </div>
308309 @*// stackedPrices for logged in users only and not working in visual editor mode*@
310 @*Stacked prices logic will not be used initially with bc. Keeping this uncommend for later.*@
311 @*@if (!Pageview.IsVisualEditorMode && !anonymousUser && product.Id != null)
312 {
313 object pricesJSON;
314 var prodID = product.Id.ToString();
315 var prod = Dynamicweb.Ecommerce.Services.Products.GetProductById(prodID, "", true);
316 var user = Pageview.User;
317 var settings = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Configuration.SettingsManager.GetSettingsByShop(Pageview.Area.EcomShopId);
318 var productInfo = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Products.ProductManager.GetProductInfo(prod, settings, user);
319320 try
321 {
322 //Handle any errors by assigning an empty object if value is not found
323 productInfo.TryGetValue("stackedPricesData", out pricesJSON);
324325 }
326 catch (Exception)
327 {
328 //return; // Cant do a return here as it will exit the whole template rendering and for example not render the "Rek. pris" logik below at all
329 pricesJSON = null; // Must assign to null otherwise error on the if statement below
330 }
331332 // Override of Stacked prices JSON for easy development/test of rendering
333 //pricesJSON = @"[
334 // {
335 // 'quantity':'4',
336 // 'price':'767.52'
337 // },
338 // {
339 // 'quantity':'10',
340 // 'price':'697.06'
341 // },
342 // {
343 // 'quantity':'100',
344 // 'price':'540.85'
345 // }
346 //]";
347348 if (pricesJSON != null && pricesJSON.ToString() != string.Empty )
349 {
350351 try
352 {
353 // Last bracket is sent in NAV response but lost in the string here
354 JArray pricesArray = JArray.Parse(pricesJSON.ToString() + "]");
355356 <div class="d-block">
357 @Translate("discontPricingTable", "Mängdrabatt - styckpris vid köp av minst:")
358 </div>
359360 <div class="bracket-price" data-id="@product.Number.ToString()">
361362 @foreach (dynamic priceLine in pricesArray)
363 {
364 double culturePrice = Convert.ToDouble(priceLine.price);
365366 <div>
367 <span class="campaign-price">
368 @priceLine.quantity @Translate("Unit", "St") @Dynamicweb.Ecommerce.Common.Context.Currency.Format(culturePrice)
369 </span>
370 </div>
371 }
372373 </div>
374375 }
376 catch
377 {
378 if (Dynamicweb.Frontend.PageView.Current().Page.NavigationTag == "ProductDetailPage") {
379 <p class="campaign-price">@Translate("StackedPricesBadDataFormatMessage", "Kontakta oss för information om mängdrabatter.")</p>
380 }
381 }
382 }
383384 }*@
385386387 @if (showPricesWithVat == "false" && !neverShowVat)
388 {
389 string productPriceConsumerOld = string.Empty;
390 string productPriceConsumer = string.Empty;
391392 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
393 {
394 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small>
395 }
396 else
397 {
398 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted;
399400 if (!anonymousUser)
401 {
402 productPriceConsumerOld = App_Code.Capo_Helpers.FormatStringPriceIncExTax(Dynamicweb.Core.Converter.ToString(product.ProductFields["productPriceOld"].Value), true);
403404 productPriceConsumer = App_Code.Capo_Helpers.GetDbPrice(product.Id, "ProductPrice");
405 productPriceConsumer = App_Code.Capo_Helpers.FormatStringPriceIncExTax(productPriceConsumer.ToString(), true);
406 }
407408 if (product?.VariantInfo?.VariantInfo != null)
409 {
410 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : "";
411 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : "";
412 }
413 if (priceMin != priceMax)
414 {
415 price = priceMin + " - " + priceMax;
416417 }
418 if (isCampaign && (Model.PageID == @GetPageIdByNavigationTag("ProductDetailsComponent") || Dynamicweb.Frontend.PageView.Current().Page.NavigationTag == "ProductDetailPage") || isOutlet && (Model.PageID == @GetPageIdByNavigationTag("ProductDetailsComponent") || Dynamicweb.Frontend.PageView.Current().Page.NavigationTag == "ProductDetailPage"))
419 {
420 <span class="my-2 d-inline-block d-flex">
421 @Translate("RRP", "Rek. konsumentpris (inkl moms): ")
422 <text class="opacity-85 fst-normal campaign-price">@productPriceConsumer </text>
423 <text class="opacity-85 fst-normal text-decoration-line-through">@productPriceConsumerOld</text>
424 </span>
425 }
426 else
427 {
428429 if (Model.PageID == @GetPageIdByNavigationTag("ProductDetailsComponent") || Dynamicweb.Frontend.PageView.Current().Page.NavigationTag == "ProductDetailPage")
430 {
431 <div class="my-2" style="white-space: pre">
432 @Translate("RRP", "Rek. konsumentpris (inkl moms): ")
433 <small class="opacity-85 fst-normal">@productPriceConsumer</small>
434 </div>
435 }
436 else
437 {
438439 if (!anonymousUser)
440 {
441 <div class="my-2">
442 <span class="text-price fs-3"><b>@product.GetPrice(unitId).Price.PriceWithoutVat.ToString()</b></span>
443 </div>
444 }
445 else
446 {
447 <div class="text-uppercase my-2 ">
448 <span class="text-price fs-3"><b>@App_Code.Capo_Helpers.FormatStringPriceIncExTax(price, true)</b></span>
449 </div>
450 }
451 }
452 }
453 }
454 }
455 </div>
456 }
457 else if (Pageview.IsVisualEditorMode)
458 {
459 <div class="alert alert-dark m-0" role="alert">
460 <span>@Translate("No products available")</span>
461 </div>
462 }
463