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_69d902058f7846909d24c88ff8ebb46a.Execute() in D:\dynamicweb.net\Solutions\Capo\sundqvist-new.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift_custom\Paragraph\Swift_ProductPrice.cshtml:line 51
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 19 20 ProductViewModel product = new ProductViewModel();
21 22 23 24 ProductViewModelSettings productSetting = new ProductViewModelSettings
25 {
26 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID,
27 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code,
28 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2,
29 ShopId = Pageview.Area.EcomShopId,
30 31 };
32 33 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
34 {
35 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
36 }
37 else if (Pageview.Item["DummyProduct"] != null)
38 {
39 40 string dummyProductId = "";
41 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
42 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
43 if (productList.Products != null)
44 {
45 foreach (var p in productList.Products) { dummyProductId = p.Id; }
46 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel();
47 product = dummyProduct;
48 }
49 else
50 {
51 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id);
52 }
53 }
54 else if (Pageview.Item["DummyProduct"] == null)
55 {
56 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id);
57 }
58 59 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", "");
60 bool anonymousUser = Pageview.User == null;
61 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); ;
62 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown;
63 64 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice");
65 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty;
66 67 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2");
68 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", "");
69 string layout = Model.Item.GetRawValueString("Layout", "horizontal");
70 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty;
71 textAlign = horizontalAlign == "end" ? "text-end" : textAlign;
72 73 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign;
74 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign;
75 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign;
76 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign;
77 78 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column";
79 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty;
80 string order = layout == "horizontal" ? string.Empty : "order-2";
81 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
82 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme;
83 84 string contentPadding = Model.Item.GetRawValueString("ContentPadding", "");
85 contentPadding = contentPadding == "none" ? "p-0" : contentPadding;
86 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding;
87 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding;
88 89 }
90 91 @if (!hidePrice && product.Id != null)
92 {
93 bool isDAP = Pageview.AreaSettings.GetBoolean("IsDigitalPortalSite");
94 string showPricesWithVat = isDAP ? "false" : Pageview.Area.EcomPricesWithVat.ToLower();
95 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat);
96 string vatText = showPricesWithVat == "true" ? Translate("Incl. VAT") : Translate("Excl. VAT");
97 98 99 string priceMin = "";
100 string priceMax = "";
101102 string liveInfoClass = "";
103 string productInfoFeed = "";
104 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]);
105 bool isCampaign = Dynamicweb.Core.Converter.ToBoolean(product.ProductFields["productCampaign"].Value);
106 bool isOutlet = Dynamicweb.Core.Converter.ToBoolean(product.ProductFields["productOutlet"].Value);
107 bool isDisableAddtoCart = Pageview.AreaSettings.GetBoolean("DisableAddToCart");
108 if (isLazyLoadingForProductInfoEnabled)
109 {
110 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
111 {
112 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
113 if (!string.IsNullOrEmpty(productInfoFeed))
114 {
115 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
116 }
117 }
118 liveInfoClass = "js-live-info";
119 }
120121 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" @productInfoFeed>
122 @if (showInformativePrice && product.PriceInformative.Price != 0)
123 {
124 <div class="opacity-50">
125126 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span>
127 </div>
128 }
129 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign" itemprop="offers" itemscope itemtype="https://schema.org/Offer">
130 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
131132133 @if (showPricesWithVat == "false" && !neverShowVat)
134 {
135136 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
137 {
138139 <span itemprop="price" content="" class="d-none"></span>
140 <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>
141 }
142 else
143 {
144145 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted;
146147 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span>
148 if (product.Price.Price != product.PriceBeforeDiscount.Price)
149 {
150 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span>
151 }
152153 }
154155 }
156 else
157 {
158159 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
160 {
161 <span itemprop="price" content="" class="d-none"></span>
162 <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>
163 }
164 else
165 {
166167 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted;
168169 <span itemprop="price" content="@product.Price.Price" class="d-none"></span>
170171 if (product.Price.Price != product.PriceBeforeDiscount.Price)
172 {
173 <span class="text-decoration-line-through opacity-75 @order">
174 <span class="text-price">@beforePrice</span>
175 </span>
176177 }
178 }
179180 }
181182 @if (showPricesWithVat == "false" && !neverShowVat)
183 {
184185186 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
187 {
188 <span class="text-price js-text-price">
189 <span class="spinner-border" role="status"></span>
190 </span>
191192 }
193 else
194 {
195196 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted;
197 //logic for displaying VAT text for anonymous users
198 price = isDAP && anonymousUser ? $"{price} <span class=\"small\">{vatText}</span>" : price;
199200 if (product?.VariantInfo?.VariantInfo != null)
201 {
202 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : "";
203 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : "";
204 }
205 if (priceMin != priceMax)
206 {
207 price = priceMin + " - " + priceMax;
208 }
209210 if (Model.PageID == GetPageIdByNavigationTag("ProductDetailsComponent"))
211 {
212 <div>
213 <span class="fs-3 mb-1"><b>@price</b></span>
214 </div>
215 }
216217 }
218 }
219 else
220 {
221 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
222 {
223 <span class="text-price js-text-price">
224 <span class="spinner-border" role="status"></span>
225 </span>
226 }
227 else
228 {
229230 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted;
231232 if (anonymousUser)
233 {
234235 // Actual system price just visually remove 00 decimals if the price is already round
236 price = product.Price.PriceWithVatFormatted.Replace(",00", "");
237 // Perform rounding of anonymous prices that are not rounded - with custom formatting function
238 //price = App_Code.Capo_Helpers.FormatStringPriceIncExTax(product.Price.PriceWithoutVat.ToString(), true);
239240 }
241242 if (product?.VariantInfo?.VariantInfo != null)
243 {
244 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : "";
245 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : "";
246 }
247 if (priceMin != priceMax)
248 {
249 price = priceMin + " - " + priceMax;
250 }
251252 if (isCampaign && Model.PageID == GetPageIdByNavigationTag("ProductDetailsComponent") && !isDisableAddtoCart || isOutlet && Model.PageID == GetPageIdByNavigationTag("ProductDetailsComponent") && !isDisableAddtoCart)
253 {
254 if (anonymousUser)
255 {
256 string productPriceConsumerOld = string.Empty;
257 productPriceConsumerOld = Dynamicweb.Core.Converter.ToString(product.ProductFields["productPriceOld"].Value);
258 string productPriceConsumerOldFormatted = App_Code.Capo_Helpers.FormatStringPriceIncExTax(productPriceConsumerOld, true);
259260 <span class="@theme @contentPadding" >
261 <span class="text-price campaign-price fs-3"><b>@price </b></span>
262 <span class="text-price text-decoration-line-through"><b>@productPriceConsumerOldFormatted</b></span>
263 </span>
264 }
265 else
266 {
267 <span class="@theme @contentPadding">
268 <span class="text-price campaign-price fs-3">@price</span>
269 </span>
270 }
271 }
272 else
273 {
274 if (anonymousUser)
275 {
276 //Slider
277 if (isCampaign && !isDisableAddtoCart || isOutlet && !isDisableAddtoCart)
278 {
279 string productPriceConsumerOld = string.Empty;
280 productPriceConsumerOld = Dynamicweb.Core.Converter.ToString(product.ProductFields["productPriceOld"].Value);
281 string productPriceConsumerOldFormatted = App_Code.Capo_Helpers.FormatStringPriceIncExTax(productPriceConsumerOld, true);
282283 <span class="@theme @contentPadding" >
284 <span class="text-price campaign-price fs-3"><b>@price </b></span><br>
285 <span class="text-price text-decoration-line-through"><b>@productPriceConsumerOldFormatted</b></span>
286 </span>
287 }
288 else
289 {
290 <span class="@theme @contentPadding">
291 <span class="text-price fs-3"><b>@price</b></span>
292 </span>
293 }
294 }
295 }
296 }
297 }
298299 @* Stock state for Schema.org, start *@
300 @{
301 Uri url = Dynamicweb.Context.Current.Request.Url;
302 }
303304 <link itemprop="url" href="@url">
305306 @{
307 bool IsNeverOutOfStock = product.NeverOutOfstock;
308 }
309310 @if (IsNeverOutOfStock)
311 {
312 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span>
313 }
314 else
315 {
316 if (product.StockLevel > 0)
317 {
318 <span itemprop="availability" class="d-none">InStock</span>
319 }
320 else
321 {
322 <span itemprop="availability" class="d-none">OutOfStock</span>
323 }
324 }
325 @* Stock state for Schema.org, stop *@
326327 </div>
328329 @*// stackedPrices for logged in users only and not working in visual editor mode*@
330 @*Stacked prices logic will not be used initially with bc. Keeping this uncommend for later.*@
331 @*@if (!Pageview.IsVisualEditorMode && !anonymousUser && product.Id != null)
332 {
333 object pricesJSON;
334 var prodID = product.Id.ToString();
335 var prod = Dynamicweb.Ecommerce.Services.Products.GetProductById(prodID, "", true);
336 var user = Pageview.User;
337 var settings = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Configuration.SettingsManager.GetSettingsByShop(Pageview.Area.EcomShopId);
338 var productInfo = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Products.ProductManager.GetProductInfo(prod, settings, user);
339340 try
341 {
342 //Handle any errors by assigning an empty object if value is not found
343 productInfo.TryGetValue("stackedPricesData", out pricesJSON);
344345 }
346 catch (Exception)
347 {
348 //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
349 pricesJSON = null; // Must assign to null otherwise error on the if statement below
350 }
351352 // Override of Stacked prices JSON for easy development/test of rendering
353 //pricesJSON = @"[
354 // {
355 // 'quantity':'4',
356 // 'price':'767.52'
357 // },
358 // {
359 // 'quantity':'10',
360 // 'price':'697.06'
361 // },
362 // {
363 // 'quantity':'100',
364 // 'price':'540.85'
365 // }
366 //]";
367368 if (pricesJSON != null && pricesJSON.ToString() != string.Empty )
369 {
370371 try
372 {
373 // Last bracket is sent in NAV response but lost in the string here
374 JArray pricesArray = JArray.Parse(pricesJSON.ToString() + "]");
375376 <div class="d-block">
377 @Translate("discontPricingTable", "Mängdrabatt - styckpris vid köp av minst:")
378 </div>
379380 <div class="bracket-price" data-id="@product.Number.ToString()">
381382 @foreach (dynamic priceLine in pricesArray)
383 {
384 double culturePrice = Convert.ToDouble(priceLine.price);
385386 <div>
387 <span class="campaign-price">
388 @priceLine.quantity @Translate("Unit", "St") @Dynamicweb.Ecommerce.Common.Context.Currency.Format(culturePrice)
389 </span>
390 </div>
391 }
392393 </div>
394395 }
396 catch
397 {
398 if (Dynamicweb.Frontend.PageView.Current().Page.NavigationTag == "ProductDetailPage") {
399 <p class="campaign-price">@Translate("StackedPricesBadDataFormatMessage", "Kontakta oss för information om mängdrabatter.")</p>
400 }
401 }
402 }
403404 }*@
405406407 @if (showPricesWithVat == "false" && !neverShowVat && !isDAP)
408 {
409 string productPriceConsumerOld = string.Empty;
410 string productPriceConsumer = string.Empty;
411412 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
413 {
414 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small>
415 }
416 else
417 {
418 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted;
419420 if (!anonymousUser)
421 {
422 productPriceConsumerOld = App_Code.Capo_Helpers.FormatStringPriceIncExTax(Dynamicweb.Core.Converter.ToString(product.ProductFields["productPriceOld"].Value), true);
423424 productPriceConsumer = App_Code.Capo_Helpers.GetDbPrice(product.Id, "ProductPrice");
425 productPriceConsumer = App_Code.Capo_Helpers.FormatStringPriceIncExTax(productPriceConsumer.ToString(), true);
426 }
427428 if (product?.VariantInfo?.VariantInfo != null)
429 {
430 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : "";
431 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : "";
432 }
433 if (priceMin != priceMax)
434 {
435 price = priceMin + " - " + priceMax;
436437 }
438 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"))
439 {
440441 <span class="my-2 d-inline-block d-flex">
442 @Translate("RRP", "Rek. konsumentpris (inkl moms): ")
443 <text class="opacity-85 fst-normal campaign-price">@productPriceConsumer </text>
444 <text class="opacity-85 fst-normal text-decoration-line-through">@productPriceConsumerOld</text>
445 </span>
446 }
447 else
448 {
449450 if (Model.PageID == @GetPageIdByNavigationTag("ProductDetailsComponent") || Dynamicweb.Frontend.PageView.Current().Page.NavigationTag == "ProductDetailPage")
451 {
452453 <div class="my-2" style="white-space: pre">
454 @Translate("RRP", "Rek. konsumentpris (inkl moms): ")
455 <small class="opacity-85 fst-normal">@productPriceConsumer</small>
456 </div>
457 }
458 else
459 {
460461 if (!anonymousUser)
462 {
463 <div class="my-2">
464 <span class="text-price fs-3"><b>@product.GetPrice(unitId).Price.PriceWithoutVat.ToString()</b></span>
465 </div>
466 }
467 else
468 {
469 <div class="text-uppercase my-2 ">
470 <span class="text-price fs-3"><b>@App_Code.Capo_Helpers.FormatStringPriceIncExTax(price, true)</b></span>
471 </div>
472 }
473 }
474 }
475 }
476 }
477 </div>
478 }
479 else if (Pageview.IsVisualEditorMode)
480 {
481 <div class="alert alert-dark m-0" role="alert">
482 <span>@Translate("No products available")</span>
483 </div>
484 }
485