Error executing template "/Designs/Swift/Paragraph/Swift_ProductPrice_Custom.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_eedeb28f5c534b28a29c4c67f934f12e.Execute() in D:\dynamicweb.net\Solutions\brdklee.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\Paragraph\Swift_ProductPrice_Custom.cshtml:line 31
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 System.Linq;
4 @using Dynamicweb.Environment;
5 @using Dynamicweb.Core;
6 @using CustomCode.Models;
7 @using CustomCode.Helpers;
8
9 @{
10 ProductViewModel product = null;
11 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
12 {
13 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
14 }
15 else if (Pageview.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode)
16 {
17 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
18 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
19
20 if (productList?.Products is object)
21 {
22 product = productList.Products[0];
23 }
24 }
25 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", "");
26 bool anonymousUser = Pageview.User == null;
27 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]);
28 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown;
29
30 bool productIsDiscontinued = product is object && product.Discontinued;
31 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued");
32 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued;
33 }
34 @if (!hidePrice && product != null && product.Id != null && !isDiscontinued)
35 {
36 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice");
37 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty;
38
39 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2");
40 int priceFontSizeNumber = int.Parse(string.Concat(priceFontSize.Where(Char.IsDigit)));
41 string priceTextFontSize = "fs-" + (priceFontSizeNumber + 2).ToString();
42 string badgeFontSize = "fs-" + (priceFontSizeNumber > 3 ? priceFontSizeNumber - 2 : 1).ToString();
43
44 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", "");
45 string layout = Model.Item.GetRawValueString("Layout", "horizontal");
46 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty;
47 textAlign = horizontalAlign == "end" ? "text-end" : textAlign;
48
49 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign;
50 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign;
51 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign;
52 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign;
53
54 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column";
55 string flexGap = layout == "horizontal" ? "gap-3" : "gap-2";
56 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
57 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme;
58
59 string contentPadding = Model.Item.GetRawValueString("ContentPadding", "");
60 contentPadding = contentPadding == "none" ? "p-0" : contentPadding;
61 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding;
62 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding;
63
64 var user = Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser();
65
66 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower();
67 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat);
68
69 string priceMin;
70 string priceMax;
71 double minQty = (product.PurchaseMinimumQuantity ?? 1) == 0 ? 1 : (double)product.PurchaseMinimumQuantity;
72
73 string liveInfoClass = "";
74 string productInfoFeed = "";
75
76 List<SalesAgreement> salesAgreements = SalesAgreementHelper.GetSalesAgreements();
77 List<string> ItemNumbers = new List<string>();
78 bool containsSaleAgreement = false;
79
80 foreach (SalesAgreement salesAgreement in salesAgreements)
81 {
82 foreach (SalesAgreementLine item in salesAgreement.Items)
83 {
84 ItemNumbers.Add(item.ItemNumber);
85 }
86 }
87 if (ItemNumbers.Contains(product.Number))
88 {
89 containsSaleAgreement = true;
90 }
91
92 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]);
93 if (isLazyLoadingForProductInfoEnabled)
94 {
95 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
96 {
97 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
98 if (!string.IsNullOrEmpty(productInfoFeed))
99 {
100 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
101 }
102 }
103 liveInfoClass = "js-live-info";
104 }
105
106 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed>
107 @if (product.Price.Price == 0)
108 {
109 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign @theme justify-content-end" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
110 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
111 <span class="@theme @contentPadding">
112 <span class="text-price">@Translate("Unknown Price")</span>
113 </span>
114 </div>
115 }
116 else if (containsSaleAgreement == true)
117 {
118 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign @theme justify-content-end" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
119 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
120 <span class="@theme @contentPadding">
121 <span class="text-price">@Translate("Price for sales agreement")</span>
122 </span>
123 </div>
124 }
125 else
126 {
127
128 if (showInformativePrice && product.PriceInformative.Price != 0)
129 {
130 <div class="opacity-50">
131 <span>@Translate("RRP") </span>
132 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span>
133 </div>
134 }
135
136
137 <div class="@priceTextFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign @theme justify-content-end" itemprop="offers" itemscope itemtype="https://schema.org/Offer">
138 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
139
140 @* Price *@
141 @if (showPricesWithVat == "false" && !neverShowVat)
142 {
143 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
144 {
145 <span itemprop="price" content="" class="d-none"></span>
146 <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>
147
148 }
149 else
150 {
151 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted;
152 string standardPrice = !string.IsNullOrEmpty(unitId) ? product.PriceInformative.PriceWithoutVatFormatted : product.PriceInformative.PriceWithoutVatFormatted;
153 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span>
154
155 <div class="order-1 @contentPadding">
156 <div class="PersonalPriceToggle">
157 <span class="custom-price">
158 @Translate("Pris per") 1 @Translate("stk.")
159 </span>
160 <span class="custom-price @priceFontSize ">@beforePrice</span>
161 <span class="custom-price">@Translate("ekskl. moms")</span>
162 @if (product.Price.Price == product.PriceBeforeDiscount.Price)
163 {
164 <span class="custom-price">@Translate("Mindstekøb:") @minQty @Translate("stk.")</span>
165 }
166 </div>
167
168 <div class="StandardPriceToggle" hidden>
169 @if (!string.IsNullOrWhiteSpace(standardPrice))
170 {
171 <span class="custom-price">
172 @Translate("Pris per") 1 @Translate("stk.")
173 </span>
174 <span class="custom-price @priceFontSize">@standardPrice</span>
175 <span class="custom-price">@Translate("ekskl. moms")</span>
176 if (product.Price.Price == product.PriceBeforeDiscount.Price)
177 {
178 <span class="custom-price">@Translate("Mindstekøb:") @minQty @Translate("stk.")</span>
179 }
180 }
181 else
182 {
183 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign @theme justify-content-end" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
184 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
185 <span class="@theme @contentPadding">
186 <span class="text-price">@Translate("Unknown Price")</span>
187 </span>
188 </div>
189 }
190 </div>
191 </div>
192 }
193 }
194 else
195 {
196 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
197 {
198 <span itemprop="price" content="" class="d-none"></span>
199 <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>
200 }
201 else
202 {
203 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithVatFormatted : product.PriceBeforeDiscount.PriceWithVatFormatted;
204 string standardPrice = !string.IsNullOrEmpty(unitId) ? product.PriceInformative.PriceWithVatFormatted : product.PriceInformative.PriceWithVatFormatted;
205 <span itemprop="price" content="@product.Price.PriceWithVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span>
206
207 <div class="order-1 @contentPadding ">
208 <div class="PersonalPriceToggle">
209 <span class="custom-price">
210 @Translate("Pris per") 1 @Translate("stk.")
211 </span>
212 <span class="custom-price @priceFontSize ">@beforePrice</span>
213 <span class="custom-price">@Translate("inkl. moms")</span>
214 @if (product.Price.Price == product.PriceBeforeDiscount.Price)
215 {
216 <span class="custom-price">@Translate("Mindstekøb:") @minQty @Translate("stk.")</span>
217 }
218 </div>
219
220 <div class="StandardPriceToggle" hidden>
221 @if (!string.IsNullOrWhiteSpace(standardPrice))
222 {
223 <span class="custom-price">
224 @Translate("Pris per") 1 @Translate("stk.")
225 </span>
226 <span class="custom-price @priceFontSize">@standardPrice</span>
227 <span class="custom-price">@Translate("ekskl. moms")</span>
228 if (product.Price.Price == product.PriceBeforeDiscount.Price)
229 {
230 <span class="custom-price">@Translate("Mindstekøb:") @minQty @Translate("stk.")</span>
231 }
232 }
233 else
234 {
235 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign @theme justify-content-end" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
236 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
237 <span class="@theme @contentPadding">
238 <span class="text-price">@Translate("Unknown Price")</span>
239 </span>
240 </div>
241
242 }
243 </div>
244 </div>
245 }
246 }
247
248 @* Total price *@
249 @if (product.Price.Price != product.PriceBeforeDiscount.Price)
250 {
251 if (showPricesWithVat == "false" && !neverShowVat)
252 {
253 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
254 {
255 <span class="text-price js-text-price">
256 <span class="spinner-border" role="status"></span>
257 </span>
258 }
259 else
260 {
261 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted;
262
263 var badgeParms = new Dictionary<string, object>();
264 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType"));
265 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign"));
266 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign"));
267 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays"));
268 badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges"));
269
270 if (product?.VariantInfo?.VariantInfo != null)
271 {
272 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : "0";
273 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : "0";
274 if (priceMin != priceMax)
275 {
276 price = priceMin + " - " + priceMax;
277 }
278 }
279
280 <div class="order-2 @contentPadding DiscountWithBadgeToggle">
281 @if (layout == "horizontal")
282 {
283
284 <span class="custom-price">@Translate("Rabat")</span>
285 <span class="custom-price @priceFontSize">@RenderPartial("Components/EcommerceBadge_Custom.cshtml", product, badgeParms)</span>
286 }
287 else
288 {
289 <span class="custom-price @priceFontSize">@Translate("Rabat")@RenderPartial("Components/EcommerceBadge_Custom.cshtml", product, badgeParms)</span>
290 }
291 </div>
292 <div class="order-3 @contentPadding TotalPriceToggle">
293 <span class="custom-price"><br></span>
294 <span class="custom-price @priceFontSize fw-bold"> @price</span>
295 <span class="custom-price">@Translate("ekskl. moms")</span>
296 <span class="custom-price">@Translate("Mindstekøb:") @minQty @Translate("stk.")</span>
297 </div>
298 }
299 }
300 else
301 {
302 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
303 {
304 <span class="text-price js-text-price">
305 <span class="spinner-border" role="status"></span>
306 </span>
307 }
308 else
309 {
310 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted;
311
312 var badgeParms = new Dictionary<string, object>();
313 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType"));
314 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign"));
315 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign"));
316 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays"));
317 badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges"));
318
319 if (product?.VariantInfo?.VariantInfo != null)
320 {
321 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : "0";
322 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : "0";
323 if (priceMin != priceMax)
324 {
325 price = priceMin + " - " + priceMax;
326 }
327 }
328
329 if (product.Price.Price != product.PriceBeforeDiscount.Price)
330 {
331 <div class="order-2 @contentPadding DiscountWithBadgeToggle">
332 @if (layout == "horizontal")
333 {
334
335 <span class="custom-price">@Translate("Rabat")</span>
336 <span class="custom-price @priceFontSize">@RenderPartial("Components/EcommerceBadge_Custom.cshtml", product, badgeParms)</span>
337 }
338 else
339 {
340 <span class="custom-price @priceFontSize">@Translate("Rabat")@RenderPartial("Components/EcommerceBadge_Custom.cshtml", product, badgeParms)</span>
341 }
342 </div>
343 }
344 <div class="order-3 @contentPadding TotalPriceToggle">
345 <span class="custom-price"><br /></span>
346 <span class="custom-price @priceFontSize fw-bolder">@price</span>
347 <span class="custom-price">@Translate("inkl. moms")</span>
348 <span class="custom-price">@Translate("Mindstekøb:") @minQty @Translate("stk.")</span>
349 </div>
350 }
351 }
352 }
353 @*</div>*@
354 @* Stock state for Schema.org, start *@
355 @{
356 Uri url = Dynamicweb.Context.Current.Request.Url;
357 }
358
359 <link itemprop="url" href="@url">
360
361 @{
362 bool IsNeverOutOfStock = product.NeverOutOfstock;
363 }
364
365 @if (IsNeverOutOfStock)
366 {
367 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span>
368 }
369 else
370 {
371 if (product.StockLevel > 0)
372 {
373 <span itemprop="availability" class="d-none">InStock</span>
374 }
375 else
376 {
377 <span itemprop="availability" class="d-none">OutOfStock</span>
378 }
379 }
380 @* Stock state for Schema.org, stop *@
381
382 </div>
383
384 //Outcommented do to not want to show prices including VAT
385 @*if (showPricesWithVat == "false" && !neverShowVat)
386 {
387 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode)
388 {
389 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small>
390 }
391 else
392 {
393 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted;
394
395 if (product?.VariantInfo?.VariantInfo != null)
396 {
397 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : "";
398 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : "";
399 }
400 if (priceMin != priceMax)
401 {
402 price = priceMin + " - " + priceMax;
403 }
404 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small>
405 }
406 }*@
407 }
408 </div>
409 }
410 else if (Pageview.IsVisualEditorMode)
411 {
412 <div class="alert alert-dark m-0" role="alert">
413 <span>@Translate("No products available")</span>
414 </div>
415 }
416