Component builder for: Detail Page - info 1

Error executing template "Designs/Swift/Paragraph/Swift_ProductAddToCart_Custom.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_e079a9fb6e624e948defb746d64f2c02.Execute() in D:\dynamicweb.net\Solutions\Twoday\cerama.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductAddToCart_Custom.cshtml:line 32
   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 Dynamicweb.Core @*//CUSTOM*@ 4 @using Dynamicweb.Core.Encoders 5 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 6 7 @* CUSTOMIZED STANDARD SWIFT (??) TEMPLATE *@ 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.Page.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 26 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 27 bool anonymousUser = Pageview.User == null; 28 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 29 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 30 hideAddToCart = Pageview.IsVisualEditorMode ? false : hideAddToCart; 31 32 bool disablePurchase = product.ProductFields.ContainsKey("Custom_DisablePurchase") ? Convert.ToBoolean(product.ProductFields["Custom_DisablePurchase"].Value) : false; //CUSTOM 33 string disablePurchaseLink = Pageview.AreaSettings.GetItem("Custom").GetString("Custom_DisablePurchaseLink"); //CUSTOM 34 disablePurchaseLink += (!disablePurchaseLink.Contains("?") ? "?" : "&") + "Product=" + Dynamicweb.Context.Current.Server.UrlEncode(string.Format("({0}) {1}", product.Id, product.Name)); //CUSTOM 35 } 36 37 @if (product is object && !hideAddToCart) 38 { 39 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 40 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign; 41 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign; 42 horizontalAlign = horizontalAlign == "full" ? "" : horizontalAlign; 43 44 bool favoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 45 bool quantitySelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowQuantitySelector")) ? Model.Item.GetBoolean("ShowQuantitySelector") : false; 46 bool unitsSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowUnitsSelector")) ? Model.Item.GetBoolean("ShowUnitsSelector") : false; 47 bool hideInventory = !string.IsNullOrEmpty(Model.Item.GetString("HideInventory")) ? Model.Item.GetBoolean("HideInventory") : false; 48 bool hideStockState = !string.IsNullOrEmpty(Model.Item.GetString("HideStockState")) ? Model.Item.GetBoolean("HideStockState") : false; 49 50 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 51 string inputSize = string.Empty; 52 53 switch (buttonSize) 54 { 55 case "small": 56 inputSize = " input-group-sm"; 57 buttonSize = " btn-sm"; 58 break; 59 case "regular": 60 buttonSize = string.Empty; 61 break; 62 case "large": 63 inputSize = " input-group-lg"; 64 buttonSize = " btn-lg"; 65 break; 66 } 67 68 string iconPath = "/Files/icons/"; 69 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 70 if (!url.Contains("LayoutTemplate")) 71 { 72 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 73 } 74 75 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 76 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 77 bool isNeverOutOfStock = product.NeverOutOfstock; 78 disableAddToCart = isNeverOutOfStock && !isLazyLoadingForProductInfoEnabled ? "" : disableAddToCart; 79 80 string whenVariantsExist = Model.Item.GetRawValueString("WhenVariantsExist", "hide"); 81 82 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 83 string fullWidth = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "w-100" : ""; 84 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 85 string addToCartLabel = !addToCartIcon.Contains("_none") ? $"<span class=\"icon-2\">{ReadFile(addToCartIcon)}</span>" : ""; 86 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 87 addToCartLabel += !Model.Item.GetBoolean("HideButtonText") ? $"<span class=\"d-none d-md-inline\">{Translate("Add to cart")}</span><span class=\"d-inline d-md-none\">{Translate("Add")}</span>" : ""; 88 89 //CUSTOM 90 if (disablePurchase && disablePurchaseLink.IsNotNullOrEmpty()) 91 { 92 <div class="d-flex @(horizontalAlign) @(fullWidth) input-group item_@Model.Item.SystemName.ToLower()"> 93 <a class="btn btn-primary" href="@(disablePurchaseLink)" title="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:ProductAddToCart.ContactUs", "Contact us"))" rel=”nofollow”> 94 <span class="icon-2">@ReadFile("/files/Templates/Designs/Swift/Assets/icons/cerama-icons/Email-Action-Unread--Streamline-Ultimate.svg")</span> 95 </a> 96 </div> 97 } 98 else if (product.VariantInfo.VariantInfo == null || whenVariantsExist == "disable")//--CUSTOM 99 { 100 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : product.DefaultUnitId; 101 if (string.IsNullOrEmpty(unitId) && product?.UnitOptions != null) 102 { 103 if (product.UnitOptions.FirstOrDefault<UnitOptionViewModel>() != null) 104 { 105 unitId = product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Id; 106 } 107 } 108 109 string minQty = product.PurchaseMinimumQuantity != 1 ? $"min=\"{product.PurchaseMinimumQuantity.ToString()}\"" : "min=\"1\""; 110 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 111 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 112 disableAddToCart = product.VariantInfo.VariantInfo != null && string.IsNullOrEmpty(product.VariantId) ? "disabled" : disableAddToCart; 113 disableAddToCart = product.Discontinued ? "disabled" : disableAddToCart; 114 115 var reserveMode = Dynamicweb.Ecommerce.Frontend.Cart.ProductReserve.Mode; 116 117 if (unitsSelector && product.UnitOptions.Count > 0) 118 { 119 <form method="post" action="/Default.aspx?ID=@(Pageview.Page.ID)&ProductId=@product.Id" id="UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID"> 120 <input type="hidden" name="redirect" value="false"> 121 <input type="hidden" name="VariantID" value="@product.VariantId"> 122 <input type="hidden" name="UnitID" class="js-unit-id" value="@unitId"> 123 </form> 124 } 125 126 <div class="d-flex @horizontalAlign @fullWidth js-input-group item_@Model.Item.SystemName.ToLower()"> 127 <form method="post" action="@url" class="@fullWidth" style="z-index: 1"> 128 <input type="hidden" name="redirect" value="false"> 129 <input type="hidden" name="ProductId" value="@product.Id"> 130 <input type="hidden" name="ProductName" value="@HtmlEncoder.HtmlAttributeEncode(product.Name)"> @*//CUSTOM*@ 131 <input type="hidden" name="ProductVariantName" value="@HtmlEncoder.HtmlAttributeEncode(product.VariantName)"> @*//CUSTOM*@ 132 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 133 <input type="hidden" name="ProductPrice" value="@PriceViewModelExtensions.ToStringInvariant(product.Price)"> 134 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 135 <input type="hidden" name="cartcmd" value="add"> 136 137 @if (reserveMode == Dynamicweb.Ecommerce.Frontend.Cart.ProductReserveMode.AddToCart) 138 { 139 <input type="hidden" name="GetReservedAmount" value="true"> 140 } 141 142 @if (!string.IsNullOrEmpty(product.VariantId)) 143 { 144 <input type="hidden" name="VariantId" value="@product.VariantId"> 145 } 146 147 @if (!product.NeverOutOfstock) 148 { 149 <input type="hidden" name="Stock" value="@product.StockLevel"> 150 151 <template class="js-out-of-stock-notice"> 152 <div class="modal-header"> 153 <h1 class="modal-title fs-5">@Translate("Stock limit")</h1> 154 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 155 </div> 156 <div class="modal-body"> 157 @Translate("There are not enough products in stock. The product might be sold out or discontinued. Please adjust the quantity.") 158 </div> 159 </template> 160 } 161 162 @if (stepQty != "1") 163 { 164 <template class="js-step-quantity-warning"> 165 <div class="modal-header"> 166 <h1 class="modal-title fs-5">@Translate("The quantity is not valid")</h1> 167 </div> 168 <div class="modal-body"> 169 @Translate("Please select a quantity that is dividable by") @stepQty 170 </div> 171 </template> 172 } 173 @if (product.PurchaseMinimumQuantity != 1) 174 { 175 <template class="js-min-quantity-warning"> 176 <div class="modal-header"> 177 <h1 class="modal-title fs-5">@Translate("The product could not be added to the cart")</h1> 178 </div> 179 <div class="modal-body"> 180 @Translate("The quantity is not valid. You must buy at least") @product.PurchaseMinimumQuantity 181 </div> 182 </template> 183 } 184 185 @if (quantitySelector || (!anonymousUser && product.VariantInfo.VariantInfo != null) || (!anonymousUser && favoritesSelector)) 186 { 187 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId" name="UnitID" value="@unitId" /> 188 } 189 190 <div class="d-flex flex-row w-100"> 191 192 @if (!quantitySelector) 193 { 194 <input id="Quantity_@(product.Id)_@product.VariantId" class="swift_quantity_field" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> 195 } 196 197 @if (unitsSelector && product.UnitOptions.Count > 0) 198 { 199 string selectedUnitName = !string.IsNullOrEmpty(unitId) && product?.UnitOptions != null ? unitId : product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Name; 200 201 foreach (var unitOption in product.UnitOptions) 202 { 203 if (unitOption.Id == unitId) 204 { 205 selectedUnitName = unitOption.Name; 206 } 207 } 208 209 <div class="d-flex flex-column gap-2 w-100"> 210 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 211 @if (!anonymousUser && favoritesSelector) 212 { 213 @RenderPartial("Components/ToggleFavorite.cshtml", product) 214 } 215 216 @if (quantitySelector) 217 { 218 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" step="@stepQty" @minQty class="form-control swift_quantity-field" style="min-width: 60px; max-width: 100px; z-index: 1" type="number" onchange="swift.Cart.UpdateOnEnterKey(event)" onkeyup="swift.Cart.UpdateOnEnterKey(event)" @disableAddToCart> 219 } 220 221 <button class="btn btn-secondary @flexFill dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 222 @selectedUnitName 223 </button> 224 225 <ul class="dropdown-menu swift_unit-field"> 226 @foreach (var unitOption in product.UnitOptions) 227 { 228 var selectedUnit = unitOption.Id == unitId ? "selected" : ""; 229 230 <li> 231 <button type="button" class="btn dropdown-item" data-value="@unitOption.Id" onclick="document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID').querySelector('.js-unit-id').value = this.getAttribute('data-value'); 232 document.querySelector('#Unit_@(product.Id)_@product.VariantId').value = this.getAttribute('data-value'); 233 swift.PageUpdater.Update(document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID'))"> 234 <span>@unitOption.Name</span> 235 <span> 236 @if (unitOption.StockLevel > 0) 237 { 238 if (!Model.Item.GetBoolean("HideInventory")) 239 { 240 <span class="small text-success">@unitOption.StockLevel @Translate("In stock")</span> 241 } 242 else 243 { 244 <span class="small text-success">@Translate("In stock")</span> 245 } 246 } 247 else 248 { 249 <span class="small text-danger">@Translate("Out of Stock")</span> 250 } 251 </span> 252 </button> 253 </li> 254 } 255 </ul> 256 </div> 257 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary @(buttonSize) js-add-to-cart-button" style="white-space: nowrap" @disableAddToCart title="@HtmlEncoder.HtmlAttributeEncode(Translate("Add to cart"))" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> @*//CUSTOM*@ 258 @if (!Model.Item.GetBoolean("HideButtonText")) 259 { 260 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 261 @addToCartLabel 262 </span> 263 } 264 else 265 { 266 @addToCartLabel 267 } 268 </button> 269 </div> 270 } 271 else 272 { 273 if (!anonymousUser && favoritesSelector) 274 { 275 @RenderPartial("Components/ToggleFavorite.cshtml", product) 276 } 277 278 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 279 @if (quantitySelector) 280 { 281 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" step="@stepQty" @minQty class="form-control swift_quantity-field" style="min-width: 60px; max-width: 100px; z-index: 1" type="number" onchange="swift.Cart.UpdateOnEnterKey(event)" onkeyup="swift.Cart.UpdateOnEnterKey(event)" @disableAddToCart> 282 } 283 284 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary @(buttonSize) @flexFill js-add-to-cart-button" style="white-space: nowrap" @disableAddToCart title="@HtmlEncoder.HtmlAttributeEncode(Translate("Add to cart"))" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> @*//CUSTOM*@ 285 @if (!Model.Item.GetBoolean("HideButtonText")) 286 { 287 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 288 @addToCartLabel 289 </span> 290 } 291 else 292 { 293 @addToCartLabel 294 } 295 </button> 296 </div> 297 } 298 </div> 299 </form> 300 </div> 301 } 302 else if (whenVariantsExist == "modal") 303 { 304 string buttonText = Translate("Select"); 305 string variantId = !string.IsNullOrWhiteSpace(product.VariantId) ? product.VariantId : product.DefaultVariantId; 306 307 string variantSelectorServicePageId = !string.IsNullOrEmpty(Model.Item.GetString("VariantSelectorServicePageId")) ? Model.Item.GetLink("VariantSelectorServicePageId").PageId.ToString() : ""; 308 variantSelectorServicePageId = variantSelectorServicePageId != "" ? variantSelectorServicePageId : GetPageIdByNavigationTag("VariantSelectorService").ToString(); 309 310 <div class="d-flex @horizontalAlign w-100 item_@Model.Item.SystemName.ToLower()"> 311 @if (!anonymousUser && favoritesSelector) 312 { 313 @RenderPartial("Components/ToggleFavorite.cshtml", product) 314 } 315 <form action="/Default.aspx?ID=@variantSelectorServicePageId" data-response-target-element="DynamicModalContent" data-preloader="inline" style="z-index: 1" class="@fullWidth"> 316 <input type="hidden" name="ProductID" value="@product.Id"> 317 <input type="hidden" name="VariantID" value="@variantId"> 318 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()"> 319 <input type="hidden" name="HideInventory" value="@hideInventory.ToString()"> 320 <input type="hidden" name="HideStockState" value="@hideStockState.ToString()"> 321 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 322 <input type="hidden" name="ViewType" value="ModalContent"> 323 @if (isLazyLoadingForProductInfoEnabled) 324 { 325 @* If lazy loading is enabled, bypass it because we're loading a modal window, so render everything as if it was server-side *@ 326 <input type="hidden" name="getproductinfo" value="true"> 327 } 328 <button type="button" onclick="swift.PageUpdater.Update(event)" class="btn btn-primary@(buttonSize) @fullWidth" title="@HtmlEncoder.HtmlAttributeEncode(Translate("Select"))" data-bs-toggle="modal" data-bs-target="#DynamicModal" id="OpenVariantSelectorModal@(product.Id)_@Pageview.CurrentParagraph.ID">@buttonText</button> @*//CUSTOM*@ 329 </form> 330 </div> 331 } 332 } 333 else if (Pageview.IsVisualEditorMode) 334 { 335 <div class="alert alert-dark m-0">@Translate("No products available")</div> 336 } 337

Kontokunde

Handler du som erhverv, offentlig institution så har du mulighed for at få en konto hos os, der giver dig en række fordele.

By clicking 'Accept All' you consent that we may collect information about you for various purposes, including: Functionality, Statistics and Marketing