Komponent editor til: Product detail info bottom - Mobile Component

Error executing template "/Designs/Swift/Paragraph/Swift_ProductPrice_Custom.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at Smartpage.PhilipsonWine.Ecommerce.ProductInformation.ProductInformation..ctor(ProductViewModel product) in D:\a\1\s\Smartpage.PhilipsonWine.Ecommerce\ProductInformation\ProductInformation.cs:line 89
   at CompiledRazorTemplates.Dynamic.RazorEngine_626da419ee5a4905848e1c642564c8eb.Execute() in D:\dynamicweb.net\Solutions\Wineshop\Files\Templates\Designs\Swift\Paragraph\Swift_ProductPrice_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 Smartpage.PhilipsonWine.Ecommerce.ProductInformation 4 @using Smartpage.PhilipsonWine.EcomPrices 5 @using Smartpage.PhilipsonWine.EcomPrices.Models 6 @using Dynamicweb.Core 7 8 @* CUSTOMIZED STANDARD SWIFT (1.21.0) TEMPLATE *@ 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Item["DummyProduct"] != null) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 27 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 28 bool anonymousUser = Pageview.User == null; 29 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 30 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 31 32 ProductInformation productInformation = new ProductInformation(product); 33 var currentUser = Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser(); 34 //Get customer specific price and quantity 35 CustomPrice customPrice = null; 36 CustomPriceService.GetCustomPriceProducts(currentUser)?.TryGetValue(product.Id, out customPrice); 37 int kolli = productInformation.CurrentPriceQuantity; 38 39 int priceQuantity = customPrice?.PriceQuantity != null && customPrice?.PriceQuantity > 0 ? Converter.ToInt32(customPrice?.PriceQuantity) : productInformation.MaxPriceBasedOn; 40 var priceObject = new Smartpage.PhilipsonWine.Ecommerce.Prices.PriceObject(product.Id, priceQuantity, 0, productInformation.OnSale, Dynamicweb.Ecommerce.Common.Context.Currency, Dynamicweb.Ecommerce.Common.Context.Country, product.LanguageId, Pageview.Area.EcomShopId); 41 } 42 43 @if (product is object && !hidePrice) 44 { 45 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 46 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 47 48 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2"); 49 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 50 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 51 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 52 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 53 54 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 55 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 56 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 57 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 58 59 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 60 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 61 string order = layout == "horizontal" ? string.Empty : "order-0"; 62 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 63 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme; 64 65 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 66 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 67 contentPadding = contentPadding == "small" ? "p-3 p-md-3" : contentPadding; 68 contentPadding = contentPadding == "large" ? "p-5 p-md-5" : contentPadding; 69 70 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 71 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 72 73 string priceMin = ""; 74 string priceMax = ""; 75 76 string liveInfoClass = ""; 77 string productInfoFeed = ""; 78 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 79 if (isLazyLoadingForProductInfoEnabled) 80 { 81 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 82 { 83 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 84 if (!string.IsNullOrEmpty(productInfoFeed)) 85 { 86 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 87 } 88 } 89 liveInfoClass = "js-live-info"; 90 } 91 92 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower() custom" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 93 @if (showInformativePrice && product.PriceInformative.Price != 0) 94 { 95 <div> 96 <span class="@priceFontSize text-price">@product.PriceInformative.PriceFormatted</span> 97 </div> 98 } 99 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign @contentPadding" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 100 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 101 102 @if (showPricesWithVat == "false" && !neverShowVat) 103 { 104 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 105 { 106 <span class="text-price js-text-price"> 107 <span class="spinner-border" role="status"></span> 108 </span> 109 } 110 else 111 { 112 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 113 114 if (product?.VariantInfo?.VariantInfo != null) 115 { 116 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 117 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 118 } 119 if (priceMin != priceMax) 120 { 121 price = priceMin + " - " + priceMax; 122 } 123 <div class="@theme"> 124 <p class="text-price">@priceObject.DiscountPriceFormatted</p> 125 <p class="text-price-kolli">@Translate("Custom:KolliPrice", "pr. fl. v/")@kolli</p> 126 </div> 127 } 128 } 129 else 130 { 131 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 132 { 133 <span class="text-price js-text-price"> 134 <span class="spinner-border" role="status"></span> 135 </span> 136 } 137 else 138 { 139 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 140 141 if (product?.VariantInfo?.VariantInfo != null) 142 { 143 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 144 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 145 } 146 if (priceMin != priceMax) 147 { 148 price = priceMin + " - " + priceMax; 149 } 150 <div class="@theme"> 151 <p class="text-price">@priceObject.DiscountPriceFormatted</p> 152 <p class="text-price-kolli">@Translate("Custom:KolliPrice", "pr. fl. v/")@kolli</p> 153 </div> 154 } 155 } 156 157 @if (showPricesWithVat == "false" && !neverShowVat) 158 { 159 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 160 { 161 <span itemprop="price" content="" class="d-none"></span> 162 <span class="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 { 166 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 167 168 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString(System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 169 if (priceObject.NormalPrice != priceObject.DiscountPrice) 170 { 171 <span class="text-normal-price-text-before">@Translate("Custom:BeforePrice", "F�r pris:")</span> 172 <span class="text-normal-price @order">@priceObject.NormalPrice</span> 173 <span class="text-normal-price-single-bottle">@Translate("Custom:OneBottlePrice", "pr. fl.")</span> 174 } 175 } 176 } 177 else 178 { 179 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 180 { 181 <span itemprop="price" content="" class="d-none"></span> 182 <span class="opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> 183 } 184 else 185 { 186 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 187 188 <span itemprop="price" content="@product.Price.Price.ToString(System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 189 190 if (priceObject.NormalPrice != priceObject.DiscountPrice) 191 { 192 <div class="d-flex gap-1 @order"> 193 <span class="text-normal-price-text-before">@Translate("Custom:BeforePrice", "F�r pris:")</span> 194 <span class="text-normal-price">@priceObject.NormalPrice</span> 195 <span class="text-normal-price-single-bottle">@Translate("Custom:OneBottlePrice", "pr. fl.")</span> 196 </div> 197 } 198 } 199 } 200 201 @* Stock state for Schema.org, start *@ 202 @{ 203 Uri url = Dynamicweb.Context.Current.Request.Url; 204 } 205 206 <link itemprop="url" href="@url"> 207 208 @{ 209 bool IsNeverOutOfStock = product.NeverOutOfstock; 210 } 211 212 @if (IsNeverOutOfStock) 213 { 214 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 215 } 216 else 217 { 218 if (product.StockLevel > 0) 219 { 220 <span itemprop="availability" class="d-none">InStock</span> 221 } 222 else 223 { 224 <span itemprop="availability" class="d-none">OutOfStock</span> 225 } 226 } 227 @* Stock state for Schema.org, stop *@ 228 229 </div> 230 231 @if (showPricesWithVat == "false" && !neverShowVat) 232 { 233 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 234 { 235 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("Incl. VAT"))"></small> 236 } 237 else 238 { 239 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 240 241 if (product?.VariantInfo?.VariantInfo != null) 242 { 243 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 244 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 245 } 246 if (priceMin != priceMax) 247 { 248 price = priceMin + " - " + priceMax; 249 } 250 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> 251 } 252 } 253 </div> 254 } 255 else if (Pageview.IsVisualEditorMode) 256 { 257 <div class="alert alert-dark m-0" role="alert"> 258 <span>@Translate("No products available")</span> 259 </div> 260 } 261
Error executing template "Designs/Swift/Paragraph/Swift_ProductAddToCart_Custom.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at Smartpage.PhilipsonWine.Ecommerce.ProductInformation.ProductInformation..ctor(ProductViewModel product) in D:\a\1\s\Smartpage.PhilipsonWine.Ecommerce\ProductInformation\ProductInformation.cs:line 89
   at CompiledRazorTemplates.Dynamic.RazorEngine_f98b356fbabc4e619a2b138b0e6c447f.Execute() in D:\dynamicweb.net\Solutions\Wineshop\Files\Templates\Designs\Swift\Paragraph\Swift_ProductAddToCart_Custom.cshtml:line 37
   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.Ecommerce.CustomerExperienceCenter.Favorites 4 @*Custom code*@ 5 @using Smartpage.PhilipsonWine.Ecommerce.ProductInformation 6 @using Dynamicweb.Core 7 @using Smartpage.PhilipsonWine.EcomPrices 8 @using Smartpage.PhilipsonWine.EcomPrices.Models 9 @using Smartpage.Tracking.Helper 10 @using System 11 @using System.Web 12 13 14 @{ 15 ProductViewModel product = null; 16 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 17 { 18 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 19 } 20 else if (Pageview.Item["DummyProduct"] != null) 21 { 22 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 23 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 24 25 if (productList?.Products is object) 26 { 27 product = productList.Products[0]; 28 } 29 } 30 31 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 32 bool anonymousUser = Pageview.User == null; 33 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 34 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 35 hideAddToCart = Pageview.IsVisualEditorMode ? false : hideAddToCart; 36 //Custom code 37 var productField = new ProductInformation(product); 38 var kolli = productField.CurrentPriceQuantity; 39 string productLink = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?Id=" + GetPageIdByNavigationTag("Shop") + "&ProductId=" + product.Id); 40 string productImage = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + product.DefaultImage.Value; 41 var currentUser = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 42 CustomPrice customPrice = null; 43 CustomPriceService.GetCustomPriceProducts(currentUser)?.TryGetValue(product.Id, out customPrice); 44 int priceQuantity = customPrice?.PriceQuantity != null && customPrice?.PriceQuantity > 0 ? Converter.ToInt32(customPrice?.PriceQuantity) : productField.MaxPriceBasedOn; 45 string shopId = Pageview.Area.EcomShopId; 46 var priceObject = new Smartpage.PhilipsonWine.Ecommerce.Prices.PriceObject(product.Id, priceQuantity, product.Discount.Price, productField.OnSale, Dynamicweb.Ecommerce.Common.Context.Currency, Dynamicweb.Ecommerce.Common.Context.Country, product.LanguageId, shopId); 47 var productDiscount = PriceHelper.FormatPrice(priceObject.NormalPrice - priceObject.DiscountPrice); 48 string areaId = Converter.ToString(Pageview.AreaID); 49 string time = DateTime.Now.ToString("G", System.Globalization.CultureInfo.InvariantCulture); 50 string uniqueId = Guid.NewGuid().ToString("N"); 51 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 52 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 53 contentPadding = contentPadding == "small" ? "p-3 p-md-3" : contentPadding; 54 contentPadding = contentPadding == "large" ? "p-5 p-md-5" : contentPadding; 55 } 56 57 @if (product is object && !hideAddToCart) 58 { 59 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 60 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign; 61 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign; 62 horizontalAlign = horizontalAlign == "full" ? "" : horizontalAlign; 63 64 bool favoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 65 bool quantitySelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowQuantitySelector")) ? Model.Item.GetBoolean("ShowQuantitySelector") : false; 66 bool unitsSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowUnitsSelector")) ? Model.Item.GetBoolean("ShowUnitsSelector") : false; 67 bool hideInventory = !string.IsNullOrEmpty(Model.Item.GetString("HideInventory")) ? Model.Item.GetBoolean("HideInventory") : false; 68 bool hideStockState = !string.IsNullOrEmpty(Model.Item.GetString("HideStockState")) ? Model.Item.GetBoolean("HideStockState") : false; 69 70 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 71 string inputSize = string.Empty; 72 73 switch (buttonSize) 74 { 75 case "small": 76 inputSize = " input-group-sm"; 77 buttonSize = " btn-sm"; 78 break; 79 case "regular": 80 buttonSize = string.Empty; 81 break; 82 case "large": 83 inputSize = " input-group-lg"; 84 buttonSize = " btn-lg"; 85 break; 86 } 87 88 string iconPath = "/Files/icons/"; 89 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 90 if (!url.Contains("LayoutTemplate")) 91 { 92 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 93 } 94 95 bool outOfStock = (product.StockLevel <= 0); 96 string hideColliClass = outOfStock ? "d-none" : ""; 97 string disableAddToCart = outOfStock ? "disabled" : ""; 98 bool isNeverOutOfStock = product.NeverOutOfstock; 99 disableAddToCart = isNeverOutOfStock ? "" : disableAddToCart; 100 101 string soldOutBorderRadiusClass = outOfStock ? "sold-out-button" : ""; 102 103 string whenVariantsExist = Model.Item.GetRawValueString("WhenVariantsExist", "hide"); 104 105 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 106 string fullWidth = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "w-100" : ""; 107 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 108 string addToCartLabel = !addToCartIcon.Contains("_none") ? "<span class=\"icon-2\">" + ReadFile(addToCartIcon) + "</span>" : ""; 109 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 110 addToCartLabel += !Model.Item.GetBoolean("HideButtonText") && !outOfStock ? Translate("Add to cart") : Translate("Sold out"); 111 112 if (product.VariantInfo.VariantInfo == null || whenVariantsExist == "disable") 113 { 114 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : product.DefaultUnitId; 115 if (string.IsNullOrEmpty(unitId) && product?.UnitOptions != null) 116 { 117 if (product.UnitOptions.FirstOrDefault<UnitOptionViewModel>() != null) 118 { 119 unitId = product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Id; 120 } 121 } 122 123 string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; 124 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 125 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 126 disableAddToCart = product.VariantInfo.VariantInfo != null && string.IsNullOrEmpty(product.VariantId) ? "disabled" : disableAddToCart; 127 128 var reserveMode = Dynamicweb.Ecommerce.Frontend.Cart.ProductReserve.Mode; 129 130 if (unitsSelector && product.UnitOptions.Count > 0) 131 { 132 <form method="post" action="/Default.aspx?ID=@(Pageview.Page.ID)&ProductId=@product.Id" id="UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID"> 133 <input type="hidden" name="redirect" value="false"> 134 <input type="hidden" name="VariantID" value="@product.VariantId"> 135 <input type="hidden" name="UnitID" class="js-unit-id" value="@unitId"> 136 </form> 137 } 138 139 <div class="d-flex @horizontalAlign @fullWidth @contentPadding js-input-group item_@Model.Item.SystemName.ToLower()"> 140 <form method="post" action="@url" class="@fullWidth" style="z-index: 1"> 141 <input type="hidden" name="redirect" value="false"> 142 <input type="hidden" name="ProductId" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(product.Id)"> 143 <input type="hidden" name="ProductName" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(product.Name)"> 144 <input type="hidden" name="ProductVariantName" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(product.VariantName)"> 145 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 146 <input type="hidden" name="ProductPrice" value="@Converter.ToInt32(PriceViewModelExtensions.ToStringInvariant(product.Price))"> 147 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 148 <input type="hidden" name="cartcmd" value="add"> 149 @*Custom code*@ 150 <input type="hidden" name="ProductBrand" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productField.Brand)"> 151 <input type="hidden" name="ProductType" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productField.Type)"> 152 <input type="hidden" name="ProductPrimaryGrape" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productField.PrimaryGrape)"> 153 <input type="hidden" name="ProductCountry" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productField.Country)"> 154 <input type="hidden" name="ProductRegion" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productField.Area)"> 155 <input type="hidden" name="ProductCounty" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productField.County)"> 156 <input type="hidden" name="ProductVintage" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productField.Year)"> 157 <input type="hidden" name="ProductOnSale" value="@productField.OnSale.ToString()"> 158 <input type="hidden" name="ProductBottleSize" value="@productField.BottleSizeCl"> 159 <input type="hidden" name="ProductLink" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productLink)"> 160 <input type="hidden" name="ProductImage" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productImage)"> 161 <input type="hidden" name="ProductDiscount" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(productDiscount)"> 162 <input type="hidden" name="ShopId" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(shopId)"> 163 <input type="hidden" name="AreaId" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(areaId)"> 164 <input type="hidden" name="Time" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(time)"> 165 <input type="hidden" name="UniqueId" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(uniqueId)"> 166 167 @if (reserveMode == Dynamicweb.Ecommerce.Frontend.Cart.ProductReserveMode.AddToCart) 168 { 169 <input type="hidden" name="GetReservedAmount" value="true"> 170 } 171 172 @if (!string.IsNullOrEmpty(product.VariantId)) 173 { 174 <input type="hidden" name="VariantId" value="@product.VariantId"> 175 } 176 177 @if (!product.NeverOutOfstock) 178 { 179 <input type="hidden" name="Stock" value="@product.StockLevel"> 180 181 <template class="js-out-of-stock-notice"> 182 <div class="modal-header"> 183 <h1 class="modal-title fs-5">@Translate("Stock limit")</h1> 184 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 185 </div> 186 <div class="modal-body"> 187 @Translate("There are not enough products in stock. The product might be sold out or discontinued. Please adjust the quantity.") 188 </div> 189 </template> 190 } 191 192 @if (stepQty != "1") 193 { 194 <template class="js-step-quantity-warning"> 195 <div class="modal-header"> 196 <h1 class="modal-title fs-5">@Translate("The quantity is not valid")</h1> 197 </div> 198 <div class="modal-body"> 199 @Translate("Please select a quantity that is dividable by") @stepQty 200 </div> 201 </template> 202 } 203 @if (product.PurchaseMinimumQuantity != 1) 204 { 205 <template class="js-min-quantity-warning"> 206 <div class="modal-header"> 207 <h1 class="modal-title fs-5">@Translate("The product could not be added to the cart")</h1> 208 </div> 209 <div class="modal-body"> 210 @Translate("The quantity is not valid. You must buy at least") @product.PurchaseMinimumQuantity 211 </div> 212 </template> 213 } 214 215 @if (quantitySelector || (!anonymousUser && product.VariantInfo.VariantInfo != null) || (!anonymousUser && favoritesSelector)) 216 { 217 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId" name="UnitID" value="@unitId" /> 218 } 219 220 <div class="d-flex flex-row w-100"> 221 @if (!anonymousUser && favoritesSelector) 222 { 223 @RenderPartial("Components/ToggleFavorite.cshtml", product) 224 } 225 226 @if (!quantitySelector) 227 { 228 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@kolli" type="hidden" class="@hideColliClass">//Custom code 229 } 230 231 <div class="gap-2 input-group input-primary-button-group @(inputSize)"> 232 @if (quantitySelector) 233 { 234 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@kolli" step="@stepQty" @minQty class="rounded-3 form-control swift_quantity-field @hideColliClass" style="min-width: 60px; max-width: 100px; z-index: 1" type="number" onchange="swift.Cart.UpdateOnEnterKey(event)" onkeyup="swift.Cart.UpdateOnEnterKey(event)" @disableAddToCart>//Custom code 235 } 236 237 @if (unitsSelector && product.UnitOptions.Count > 0) 238 { 239 string selectedUnitName = !string.IsNullOrEmpty(unitId) && product?.UnitOptions != null ? unitId : product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Name; 240 241 foreach (var unitOption in product.UnitOptions) 242 { 243 if (unitOption.Id == unitId) 244 { 245 selectedUnitName = unitOption.Name; 246 } 247 } 248 249 <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 250 @selectedUnitName 251 </button> 252 <ul class="dropdown-menu swift_unit-field"> 253 @foreach (var unitOption in product.UnitOptions) 254 { 255 var selectedUnit = unitOption.Id == unitId ? "selected" : ""; 256 257 <li> 258 <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'); 259 document.querySelector('#Unit_@(product.Id)_@product.VariantId').value = this.getAttribute('data-value'); 260 swift.PageUpdater.Update(document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID'))"> 261 <span>@unitOption.Name</span> 262 <span> 263 @if (unitOption.StockLevel > 0) 264 { 265 if (!Model.Item.GetBoolean("HideInventory")) 266 { 267 <span class="small text-success">@unitOption.StockLevel @Translate("In stock")</span> 268 } 269 else 270 { 271 <span class="small text-success">@Translate("In stock")</span> 272 } 273 } 274 else 275 { 276 <span class="small text-danger">@Translate("Out of Stock")</span> 277 } 278 </span> 279 </button> 280 </li> 281 } 282 </ul> 283 } 284 285 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary fw-bold rounded-3 @(buttonSize) @flexFill js-add-to-cart-button @soldOutBorderRadiusClass" style="white-space: nowrap;" @disableAddToCart title="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("Add to cart"))" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> 286 @if (!Model.Item.GetBoolean("HideButtonText")) 287 { 288 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 289 @addToCartLabel 290 </span> 291 } 292 else 293 { 294 @addToCartLabel 295 } 296 </button> 297 298 </div> 299 </div> 300 </form> 301 </div> 302 } 303 else if (whenVariantsExist == "modal") 304 { 305 string buttonText = Translate("Select"); 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="QuantitySelector" value="@quantitySelector.ToString()"> 318 <input type="hidden" name="HideInventory" value="@hideInventory.ToString()"> 319 <input type="hidden" name="HideStockState" value="@hideStockState.ToString()"> 320 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 321 <input type="hidden" name="ViewType" value="ModalContent"> 322 <button type="button" onclick="swift.PageUpdater.Update(event)" class="btn btn-primary@(buttonSize) @fullWidth" title="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("Select"))" data-bs-toggle="modal" data-bs-target="#DynamicModal" id="OpenVariantSelectorModal@(product.Id)_@Pageview.CurrentParagraph.ID">@buttonText</button> 323 </form> 324 </div> 325 } 326 } 327 else if (Pageview.IsVisualEditorMode) 328 { 329 <div class="alert alert-dark m-0">@Translate("No products available")</div> 330 } 331

Sikker dansk webshop

Nye tilbud hver dag

Fri fragt over 799,-

Sikker fragt

Smagsgaranti

Dansk kundeservice


Hvordan er vores priser så lave?

Vi holder vores priser lave ved dagligt at overvåge det danske vinmarked og sikre, at vi altid tilbyder konkurrencedygtige priser på nøje udvalgte vine.