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_477f9454345b4eb19ccb2b59ab985635.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 80 string unitDescription = productInformation.IsBomParent ? "kasse" : "fl. v/" + kolli; 81 82 if (isLazyLoadingForProductInfoEnabled) 83 { 84 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 85 { 86 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 87 if (!string.IsNullOrEmpty(productInfoFeed)) 88 { 89 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 90 } 91 } 92 liveInfoClass = "js-live-info"; 93 } 94 95 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower() custom" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 96 @if (showInformativePrice && product.PriceInformative.Price != 0) 97 { 98 <div> 99 <span class="@priceFontSize text-price">@product.PriceInformative.PriceFormatted</span> 100 </div> 101 } 102 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign @contentPadding" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 103 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 104 105 @if (showPricesWithVat == "false" && !neverShowVat) 106 { 107 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 108 { 109 <span class="text-price js-text-price"> 110 <span class="spinner-border" role="status"></span> 111 </span> 112 } 113 else 114 { 115 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 116 117 if (product?.VariantInfo?.VariantInfo != null) 118 { 119 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 120 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 121 } 122 if (priceMin != priceMax) 123 { 124 price = priceMin + " - " + priceMax; 125 } 126 <div class="@theme"> 127 <p class="text-price">@priceObject.DiscountPriceFormatted</p> 128 <p class="text-price-kolli">@string.Format(Translate("Custom:KolliPrice", "pr. {0}"), unitDescription)</p> 129 </div> 130 } 131 } 132 else 133 { 134 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 135 { 136 <span class="text-price js-text-price"> 137 <span class="spinner-border" role="status"></span> 138 </span> 139 } 140 else 141 { 142 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 143 144 if (product?.VariantInfo?.VariantInfo != null) 145 { 146 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 147 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 148 } 149 if (priceMin != priceMax) 150 { 151 price = priceMin + " - " + priceMax; 152 } 153 <div class="@theme"> 154 <p class="text-price">@priceObject.DiscountPriceFormatted</p> 155 <p class="text-price-kolli">@string.Format(Translate("Custom:KolliPrice", "pr. {0}"), unitDescription)</p> 156 </div> 157 } 158 } 159 160 @if (showPricesWithVat == "false" && !neverShowVat) 161 { 162 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 163 { 164 <span itemprop="price" content="" class="d-none"></span> 165 <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> 166 } 167 else 168 { 169 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 170 171 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString(System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 172 if (priceObject.NormalPrice != priceObject.DiscountPrice) 173 { 174 <span class="text-normal-price-text-before">@Translate("Custom:BeforePrice", "F�r pris:")</span> 175 <span class="text-normal-price @order">@priceObject.NormalPrice</span> 176 <span class="text-normal-price-single-bottle">@Translate("Custom:OneBottlePrice", "pr. fl.")</span> 177 } 178 } 179 } 180 else 181 { 182 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 183 { 184 <span itemprop="price" content="" class="d-none"></span> 185 <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> 186 } 187 else 188 { 189 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 190 191 <span itemprop="price" content="@product.Price.Price.ToString(System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 192 193 if (priceObject.NormalPrice != priceObject.DiscountPrice) 194 { 195 <div class="d-flex gap-1 @order"> 196 <span class="text-normal-price-text-before">@Translate("Custom:BeforePrice", "F�r pris:")</span> 197 <span class="text-normal-price">@priceObject.NormalPrice</span> 198 <span class="text-normal-price-single-bottle">@Translate("Custom:OneBottlePrice", "pr. fl.")</span> 199 </div> 200 } 201 } 202 } 203 204 @* Stock state for Schema.org, start *@ 205 @{ 206 Uri url = Dynamicweb.Context.Current.Request.Url; 207 } 208 209 <link itemprop="url" href="@url"> 210 211 @{ 212 bool IsNeverOutOfStock = product.NeverOutOfstock; 213 } 214 215 @if (IsNeverOutOfStock) 216 { 217 <meta itemprop="availability" content="https://schema.org/InStock"> 218 } 219 else 220 { 221 if (product.StockLevel > 0) 222 { 223 <meta itemprop="availability" content="https://schema.org/InStock"> 224 } 225 else 226 { 227 <meta itemprop="availability" content="https://schema.org/OutOfStock"> 228 } 229 } 230 <meta itemprop="itemCondition" content="https://schema.org/NewCondition"> 231 @* Stock state for Schema.org, stop *@ 232 233 </div> 234 235 @if (showPricesWithVat == "false" && !neverShowVat) 236 { 237 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 238 { 239 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("Incl. VAT"))"></small> 240 } 241 else 242 { 243 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 244 245 if (product?.VariantInfo?.VariantInfo != null) 246 { 247 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 248 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 249 } 250 if (priceMin != priceMax) 251 { 252 price = priceMin + " - " + priceMax; 253 } 254 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> 255 } 256 } 257 </div> 258 } 259 else if (Pageview.IsVisualEditorMode) 260 { 261 <div class="alert alert-dark m-0" role="alert"> 262 <span>@Translate("No products available")</span> 263 </div> 264 } 265
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_3254d3cb94b54d3ea68b4011c366ddd0.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="ProductReferer" value="component_ProductAddToCart"> 147 <input type="hidden" name="cartcmd" value="add"> 148 @*Custom code*@ 149 <input type="hidden" name="ProductPrice" value="@Converter.ToInt32(priceObject.NormalPrice)"> 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.