Error executing template "/Designs/Swift-v2/Paragraph/Custom_Swift-v2_ProductPriceDetails.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_b494d6d97a074caf98c3a800ae8335d8.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   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 Dynamicweb.Ecommerce.Products 4 5 @{ 6 ProductViewModel product = null; 7 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 8 { 9 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 10 } else if (!string.IsNullOrEmpty(Pageview.Page.Item["DummyProduct"]?.ToString()) && Pageview.IsVisualEditorMode) 11 { 12 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 13 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 14 15 if (productList?.Products is object) 16 { 17 product = productList.Products[0]; 18 } 19 } else if (Pageview.IsVisualEditorMode) { 20 product = new ProductViewModel(); 21 product.Price = new PriceViewModel() { 22 Price = 99, 23 PriceFormatted = "99 " + Pageview.Area.EcomCurrencyId, 24 PriceWithoutVat = 99, 25 PriceWithoutVatFormatted = "99 " + Pageview.Area.EcomCurrencyId, 26 PriceWithVat = 99, 27 PriceWithVatFormatted = "99 " + Pageview.Area.EcomCurrencyId 28 }; 29 product.PriceInformative = new PriceViewModel() { 30 Price = 49, 31 PriceFormatted = "49 " + Pageview.Area.EcomCurrencyId, 32 PriceWithoutVat = 49, 33 PriceWithoutVatFormatted = "49 " + Pageview.Area.EcomCurrencyId, 34 PriceWithVat = 49, 35 PriceWithVatFormatted = "49 " + Pageview.Area.EcomCurrencyId 36 }; 37 product.PriceBeforeDiscount = new PriceViewModel() { 38 Price = 199, 39 PriceFormatted = "199 " + Pageview.Area.EcomCurrencyId, 40 PriceWithoutVat = 199, 41 PriceWithoutVatFormatted = "199 " + Pageview.Area.EcomCurrencyId, 42 PriceWithVat = 199, 43 PriceWithVatFormatted = "99 " + Pageview.Area.EcomCurrencyId 44 }; 45 } 46 47 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 48 bool anonymousUser = Pageview.User == null; 49 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser; 50 51 bool productIsDiscontinued = product is object && product.Discontinued; 52 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 53 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 54 55 string priceType = string.Empty; 56 if (Dynamicweb.Context.Current.Items.Contains("PriceType")) 57 { 58 priceType = Dynamicweb.Context.Current.Items["PriceType"].ToString().ToLower(); 59 } 60 } 61 62 @if (product is object && !hidePrice && !isDiscontinued && priceType != "fixedprice") { 63 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 64 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 65 66 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2"); 67 string? title = Model.Item.GetRawValueString("Title"); 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 82 string showPricesWithVat = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat.ToString(); 83 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 84 85 string priceMin = ""; 86 string priceMax = ""; 87 88 <div class="@textAlign item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId"> 89 @if (showInformativePrice && product.PriceInformative.Price != 0) 90 { 91 <div class="opacity-50"> 92 <span>@Translate("RRP") </span> 93 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 94 </div> 95 } 96 <div class="@priceFontSize m-0 d-flex flex-column flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 97 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 98 99 @if(!string.IsNullOrEmpty(title)) { 100 <p class="mb-0 small opacity-75 d-block">@title</p> 101 } 102 103 @if (showPricesWithVat == "false" && !neverShowVat) 104 { 105 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 106 107 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span> 108 if (product.Price.Price != product.PriceBeforeDiscount.Price) 109 { 110 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 111 } 112 } 113 else 114 { 115 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 116 117 <span itemprop="price" content="@product.Price.Price" class="d-none"></span> 118 119 if (product.Price.Price != product.PriceBeforeDiscount.Price) 120 { 121 <span class="text-decoration-line-through opacity-75 @order"> 122 <span class="text-price">@beforePrice</span> 123 </span> 124 } 125 } 126 127 @if (showPricesWithVat == "false" && !neverShowVat) 128 { 129 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 130 131 if (product?.VariantInfo?.VariantInfo != null) 132 { 133 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 134 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 135 } 136 if (priceMin != priceMax) 137 { 138 price = priceMin + " - " + priceMax; 139 } 140 141 <span class="text-price">@price</span> 142 } 143 else 144 { 145 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 146 147 if (product?.VariantInfo?.VariantInfo != null) 148 { 149 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 150 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 151 } 152 if (priceMin != priceMax) 153 { 154 price = priceMin + " - " + priceMax; 155 } 156 157 <span class="text-price">@price</span> 158 } 159 160 @* Stock state for Schema.org, start *@ 161 @{ 162 Uri url = Dynamicweb.Context.Current.Request.Url; 163 } 164 165 <link itemprop="url" href="@url"> 166 167 @{ 168 bool IsNeverOutOfStock = product.NeverOutOfstock; 169 } 170 171 @if (IsNeverOutOfStock) 172 { 173 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 174 } 175 else 176 { 177 if (product.StockLevel > 0) 178 { 179 <span itemprop="availability" class="d-none">InStock</span> 180 } 181 else 182 { 183 <span itemprop="availability" class="d-none">OutOfStock</span> 184 } 185 } 186 @* Stock state for Schema.org, stop *@ 187 188 </div> 189 190 @if (showPricesWithVat == "false" && !neverShowVat) 191 { 192 if (!Pageview.IsVisualEditorMode) 193 { 194 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 195 } 196 else 197 { 198 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 199 200 if (product?.VariantInfo?.VariantInfo != null) 201 { 202 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 203 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 204 } 205 if (priceMin != priceMax) 206 { 207 price = priceMin + " - " + priceMax; 208 } 209 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> 210 } 211 } 212 </div> 213 } 214 else if (Pageview.IsVisualEditorMode) 215 { 216 <div class="alert alert-dark m-0" role="alert"> 217 <span>@Translate("No products available")</span> 218 </div> 219 } 220 <script> 221 window.dataLayer.push({ 222 event: "view_item", 223 currency: "@product.Price.CurrencyCode", 224 value: @PriceViewModelExtensions.ToStringInvariant(product.Price), 225 ecommerce: { 226 items: [ 227 { 228 item_id: "@product.Number", 229 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(product.Name)", 230 currency: "@product.Price.CurrencyCode", 231 price: @PriceViewModelExtensions.ToStringInvariant(product.Price) 232 } 233 ] 234 } 235 }) 236 </script> 237

Product specifications

Downloads and ressources

Savings calculator

A public restroom simply has to work – even after guest number 1,000. That’s why our hand dryers are designed to be used. Again and again. They are touch-free, reliable, and energy-efficient, saving time, money, and resources compared to paper towels. No refills. No waste. No maintenance beyond the essentials. See your potential savings — on running costs, service, and environmental impact — by switching to a DAN DRYER hand dryer.

Custom solutions

Everything starts with understanding the needs of the building and its users

Every building is unique – and so are its needs. We create hygiene solutions that align with the architecture, the people, and the way the space is used. Working with you, we see the solution through from concept to completion. So everything works – day after day.