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_92a06761fba64b3d921e53207ac65cf2.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 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId" name="UnitID" value="@unitId" /> <!--CUSTOM Moved to always be included instead of logic based on quantitySelector 28707--> 137 138 @if (reserveMode == Dynamicweb.Ecommerce.Frontend.Cart.ProductReserveMode.AddToCart) 139 { 140 <input type="hidden" name="GetReservedAmount" value="true"> 141 } 142 143 @if (!string.IsNullOrEmpty(product.VariantId)) 144 { 145 <input type="hidden" name="VariantId" value="@product.VariantId"> 146 } 147 148 @if (!product.NeverOutOfstock) 149 { 150 <input type="hidden" name="Stock" value="@product.StockLevel"> 151 152 <template class="js-out-of-stock-notice"> 153 <div class="modal-header"> 154 <h1 class="modal-title fs-5">@Translate("Stock limit")</h1> 155 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 156 </div> 157 <div class="modal-body"> 158 @Translate("There are not enough products in stock. The product might be sold out or discontinued. Please adjust the quantity.") 159 </div> 160 </template> 161 } 162 163 @if (stepQty != "1") 164 { 165 <template class="js-step-quantity-warning"> 166 <div class="modal-header"> 167 <h1 class="modal-title fs-5">@Translate("The quantity is not valid")</h1> 168 </div> 169 <div class="modal-body"> 170 @Translate("Please select a quantity that is dividable by") @stepQty 171 </div> 172 </template> 173 } 174 @if (product.PurchaseMinimumQuantity != 1) 175 { 176 <template class="js-min-quantity-warning"> 177 <div class="modal-header"> 178 <h1 class="modal-title fs-5">@Translate("The product could not be added to the cart")</h1> 179 </div> 180 <div class="modal-body"> 181 @Translate("The quantity is not valid. You must buy at least") @product.PurchaseMinimumQuantity 182 </div> 183 </template> 184 } 185 186 <div class="d-flex flex-row w-100"> 187 188 @if (!quantitySelector) 189 { 190 <input id="Quantity_@(product.Id)_@product.VariantId" class="swift_quantity_field" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> 191 } 192 193 @if (unitsSelector && product.UnitOptions.Count > 0) 194 { 195 string selectedUnitName = !string.IsNullOrEmpty(unitId) && product?.UnitOptions != null ? unitId : product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Name; 196 197 foreach (var unitOption in product.UnitOptions) 198 { 199 if (unitOption.Id == unitId) 200 { 201 selectedUnitName = unitOption.Name; 202 } 203 } 204 205 <div class="d-flex flex-column gap-2 w-100"> 206 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 207 @if (!anonymousUser && favoritesSelector) 208 { 209 @RenderPartial("Components/ToggleFavorite.cshtml", product) 210 } 211 212 @if (quantitySelector) 213 { 214 <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> 215 } 216 217 <button class="btn btn-secondary @flexFill dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 218 @selectedUnitName 219 </button> 220 221 <ul class="dropdown-menu swift_unit-field"> 222 @foreach (var unitOption in product.UnitOptions) 223 { 224 var selectedUnit = unitOption.Id == unitId ? "selected" : ""; 225 226 <li> 227 <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'); 228 document.querySelector('#Unit_@(product.Id)_@product.VariantId').value = this.getAttribute('data-value'); 229 swift.PageUpdater.Update(document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID'))"> 230 <span>@unitOption.Name</span> 231 <span> 232 @if (unitOption.StockLevel > 0) 233 { 234 if (!Model.Item.GetBoolean("HideInventory")) 235 { 236 <span class="small text-success">@unitOption.StockLevel @Translate("In stock")</span> 237 } 238 else 239 { 240 <span class="small text-success">@Translate("In stock")</span> 241 } 242 } 243 else 244 { 245 <span class="small text-danger">@Translate("Out of Stock")</span> 246 } 247 </span> 248 </button> 249 </li> 250 } 251 </ul> 252 </div> 253 <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"> 254 @*//CUSTOM*@ 255 @if (!Model.Item.GetBoolean("HideButtonText")) 256 { 257 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 258 @addToCartLabel 259 </span> 260 } 261 else 262 { 263 @addToCartLabel 264 } 265 </button> 266 </div> 267 } 268 else 269 { 270 if (!anonymousUser && favoritesSelector) 271 { 272 @RenderPartial("Components/ToggleFavorite.cshtml", product) 273 } 274 275 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 276 @if (quantitySelector) 277 { 278 <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> 279 } 280 281 <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"> 282 @*//CUSTOM*@ 283 @if (!Model.Item.GetBoolean("HideButtonText")) 284 { 285 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 286 @addToCartLabel 287 </span> 288 } 289 else 290 { 291 @addToCartLabel 292 } 293 </button> 294 </div> 295 } 296 </div> 297 </form> 298 </div> 299 } 300 else if (whenVariantsExist == "modal") 301 { 302 string buttonText = Translate("Select"); 303 string variantId = !string.IsNullOrWhiteSpace(product.VariantId) ? product.VariantId : product.DefaultVariantId; 304 305 string variantSelectorServicePageId = !string.IsNullOrEmpty(Model.Item.GetString("VariantSelectorServicePageId")) ? Model.Item.GetLink("VariantSelectorServicePageId").PageId.ToString() : ""; 306 variantSelectorServicePageId = variantSelectorServicePageId != "" ? variantSelectorServicePageId : GetPageIdByNavigationTag("VariantSelectorService").ToString(); 307 308 <div class="d-flex @horizontalAlign w-100 item_@Model.Item.SystemName.ToLower()"> 309 @if (!anonymousUser && favoritesSelector) 310 { 311 @RenderPartial("Components/ToggleFavorite.cshtml", product) 312 } 313 <form action="/Default.aspx?ID=@variantSelectorServicePageId" data-response-target-element="DynamicModalContent" data-preloader="inline" style="z-index: 1" class="@fullWidth"> 314 <input type="hidden" name="ProductID" value="@product.Id"> 315 <input type="hidden" name="VariantID" value="@variantId"> 316 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()"> 317 <input type="hidden" name="HideInventory" value="@hideInventory.ToString()"> 318 <input type="hidden" name="HideStockState" value="@hideStockState.ToString()"> 319 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 320 <input type="hidden" name="ViewType" value="ModalContent"> 321 @if (isLazyLoadingForProductInfoEnabled) 322 { 323 @* If lazy loading is enabled, bypass it because we're loading a modal window, so render everything as if it was server-side *@ 324 <input type="hidden" name="getproductinfo" value="true"> 325 } 326 <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*@ 327 </form> 328 </div> 329 } 330 } 331 else if (Pageview.IsVisualEditorMode) 332 { 333 <div class="alert alert-dark m-0">@Translate("No products available")</div> 334 } 335

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