Error executing template "Designs/Swift/eCom/ProductCatalog/ProductViewDetail.cshtml"
System.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   at System.Data.SqlClient.SqlDataReader.Read()
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetAllProductKeys(String productLanguageId)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountInfoCollection.LoadDiscounts()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__40()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__42()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo)
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__43()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_f003e18c74284b42a6a0872d9dc311bd.Execute() in D:\dynamicweb.net\Solutions\Flex Media\danzafe.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\eCom\ProductCatalog\ProductViewDetail.cshtml:line 157
   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()
ClientConnectionId:c84949f9-9318-4377-9bbd-599ce5ed4a84
Error Number:1205,State:52,Class:13

1 @inherits ViewModelTemplate<ProductViewModel> 2 @using Dynamicweb.Rendering 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Core 5 @using Dynamicweb.Environment 6 @using System.Web 7 8 @{ 9 string metaDescription = string.IsNullOrEmpty(Model.MetaDescription) ? Model.Name : Model.MetaDescription; 10 string klaviyoID = Pageview.AreaSettings.GetString("KlaviyoPublicKey"); 11 12 string baseUrl = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host; 13 14 15 16 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Model.DefaultImage.Value}\">"); 17 Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{Model.Name}\">"); 18 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{metaDescription}\">"); 19 20 Pageview.Meta.AddTag("twitter:image", Model.DefaultImage.Value); 21 Pageview.Meta.AddTag("twitter:image:alt", Model.Name); 22 Pageview.Meta.AddTag("twitter:description", metaDescription); 23 } 24 25 @{ 26 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 27 { 28 Dynamicweb.Context.Current.Items["ProductDetails"] = Model; 29 } 30 else 31 { 32 Dynamicweb.Context.Current.Items.Add("ProductDetails", Model); 33 } 34 35 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 36 if (isLazyLoadingForProductInfoEnabled) 37 { 38 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 39 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 40 bool hasVariantId = !string.IsNullOrEmpty(Model.VariantId); 41 string variantIdParam = hasVariantId ? $"/{Model.VariantId}" : ""; 42 string priceFilledProperties = $"Price,PriceFormatted{(showPricesWithVat == "false" && !neverShowVat ? ",PriceWithVat,PriceWithVatFormatted" : "")}"; 43 string productInfoFeed = $@"/dwapi/ecommerce/products/{Model.Id}{variantIdParam} 44 ?UserId={Converter.ToString(Pageview.User?.ID)} 45 &LanguageId={Pageview.Area.EcomLanguageId}&CurrencyCode={Pageview.Area.EcomCurrencyId}&CountryCode={Pageview.Area.EcomCountryCode}&ShopId={Pageview.Area.EcomShopId} 46 &FilledProperties=Id,Price,PriceBeforeDiscount,StockLevel,VariantInfo,NeverOutOfstock,Prices 47 &PriceSettings.ShowPricesWithVat={Pageview.Area.EcomPricesWithVat} 48 &PriceSettings.FilledProperties={priceFilledProperties} 49 &getproductinfo=true"; 50 Dynamicweb.Context.Current.Items["ProductInfoFeed"] = productInfoFeed; 51 52 <script type="module"> 53 swift.LiveProductInfo.init(); 54 </script> 55 } 56 57 string googleTagManagerID = Pageview.AreaSettings.GetString("GoogleTagManagerID"); 58 string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); 59 60 bool allowTracking = true; 61 if (CookieManager.IsCookieManagementActive) 62 { 63 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 64 allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 65 } 66 67 if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 68 { 69 <script> 70 gtag("event", "view_item", { 71 currency: "@Model.Price.CurrencyCode", 72 value: @PriceViewModelExtensions.ToStringInvariant(Model.Price), 73 items: [ 74 { 75 item_id: "@Model.Number", 76 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Model.Name)", 77 currency: "@Model.Price.CurrencyCode", 78 price: @PriceViewModelExtensions.ToStringInvariant(Model.Price) 79 } 80 ] 81 }); 82 </script> 83 } 84 85 if ((!string.IsNullOrWhiteSpace(klaviyoID))) 86 { 87 88 ProductViewModelSettings productSetting = new ProductViewModelSettings 89 { 90 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 91 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 92 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 93 ShopId = Pageview.Area.EcomShopId 94 }; 95 96 var productViewModel = ViewModelFactory.CreateView(productSetting, Model.Id, Model.VariantId); 97 98 string productLink = baseUrl + "/" + productViewModel.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 99 100 string defaultProductImage = productViewModel.DefaultImage.Value; 101 102 defaultProductImage = baseUrl + "/" + defaultProductImage; 103 104 string categories = ""; 105 106 var i=0; 107 var count = Model.ProductCategories.Count(); 108 109 foreach (var category in Model.ProductCategories){ 110 categories += category.Value.Name; 111 112 if (++i != count){ 113 categories += ", "; 114 } 115 116 117 } 118 119 120 121 var groups = Model.ProductCategories; 122 123 string brandName = ""; 124 125 foreach (var group in groups) { 126 foreach (var field in group.Value.Fields){ 127 if (field.Value.Name == "Brand"){ 128 if (field.Value.Value != null){ 129 brandName = field.Value.Value.ToString(); 130 } 131 } 132 } 133 } 134 135 136 137 if ((!string.IsNullOrWhiteSpace(Converter.ToString(Pageview.User?.Email)))) 138 { 139 <script> 140 141 klaviyo.identify({ 142 '$email' : '@(Converter.ToString(Pageview.User?.Email))', 143 '$first_name' : '@(Converter.ToString(Pageview.User?.Name))' 144 }); 145 146 </script> 147 } 148 149 <script type="text/javascript"> 150 var item = { 151 "ProductName": "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Model.Name)", 152 "ProductID": "@Model.Number", 153 "Categories": "@(categories)", 154 "ImageURL": "@defaultProductImage", 155 "URL": "@(productLink)", 156 "Brand": "@(brandName)", 157 "Price": @PriceViewModelExtensions.ToStringInvariant(Model.Price) 158 }; 159 klaviyo.push(["track", "Viewed Product", item]); 160 </script> 161 162 163 <script> 164 165 166 klaviyo.push(["trackViewedItem", { 167 "Title": "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Model.Name)", 168 "ItemId": "@Model.Number", 169 "Categories": "@(categories)", 170 "ImageUrl": "@defaultProductImage", 171 "Url": "@(productLink)", 172 "Metadata": { 173 "Price": @PriceViewModelExtensions.ToStringInvariant(Model.Price) 174 } 175 }]); 176 </script> 177 178 } 179 } 180 181 <script> 182 window.addEventListener('load', function (event) { 183 swift.Video.init(); 184 }); 185 </script> 186
Error executing template "Designs/Swift/Paragraph/Swift_ProductDetailsImage.cshtml"
System.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   at System.Data.SqlClient.SqlDataReader.Read()
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetAllProductKeys(String productLanguageId)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountInfoCollection.LoadDiscounts()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__40()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo)
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__45()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_8c3cf05c01204d4f825bf2123b765dc3.Execute() in D:\dynamicweb.net\Solutions\Flex Media\danzafe.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\Paragraph\Swift_ProductDetailsImage.cshtml:line 122
   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()
ClientConnectionId:c84949f9-9318-4377-9bbd-599ce5ed4a84
Error Number:1205,State:52,Class:13

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Frontend 4 @using System.IO 5 6 @functions { 7 public ProductViewModel product { get; set; } = new ProductViewModel(); 8 public string galleryLayout { get; set; } 9 public string[] supportedImageFormats { get; set; } 10 public string[] supportedVideoFormats { get; set; } 11 public string[] supportedDocumentFormats { get; set; } 12 public string[] allSupportedFormats { get; set; } 13 14 public class RatioSettings { 15 public string Ratio { get; set; } 16 public string CssClass { get; set; } 17 public string CssVariable { get; set; } 18 public string Fill { get; set; } 19 } 20 21 public RatioSettings GetRatioSettings(string size = "desktop") { 22 var ratioSettings = new RatioSettings(); 23 24 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 25 ratio = ratio != "0" ? ratio : ""; 26 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 27 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 28 cssClass = ratio == "fill" && size == "mobile" ? " ratio" : cssClass; 29 cssVariable = ratio == "fill" && size == "mobile" ? "--bs-aspect-ratio: 66%" : cssVariable; 30 31 ratioSettings.Ratio = ratio; 32 ratioSettings.CssClass = cssClass; 33 ratioSettings.CssVariable = cssVariable; 34 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 35 36 return ratioSettings; 37 } 38 39 public string GetArrowsColor() 40 { 41 var invertColor = Model.Item.GetBoolean("InvertModalArrowsColor"); 42 var arrowsColor = invertColor ? " carousel-dark" : string.Empty; 43 return arrowsColor; 44 } 45 } 46 47 @{ 48 ProductViewModel product = null; 49 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 50 { 51 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 52 } 53 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 54 { 55 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 56 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 57 58 if (productList?.Products is object) 59 { 60 product = productList.Products[0]; 61 } 62 } 63 } 64 65 @if (product is object) { 66 @* Supported formats *@ 67 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; 68 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; 69 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", "pptx" }; 70 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); 71 72 @* Collect the assets *@ 73 var selectedAssetCategories = Model.Item.GetRawValueString("ImageAssets").Split(',').ToList(); 74 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); 75 76 @* Needed image data collection to support both DefaultImage, ImagePatterns and Image Assets *@ 77 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 78 IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 79 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); 80 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[]{}; 81 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; 82 assetsList = assetsList.Union(assetsImages); 83 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; 84 85 86 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); 87 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); 88 89 int totalAssets = 0; 90 if (showOnlyPrimaryImage == false) { 91 foreach (MediaViewModel asset in assetsList) { 92 var assetValue = asset.Value; 93 foreach (string format in allSupportedFormats) { 94 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { 95 totalAssets++; 96 } 97 } 98 } 99 } 100 101 if((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null) || totalAssets == 0 && defaultImageFallback) 102 { 103 assetsList = new List<MediaViewModel>(){ product.DefaultImage }; 104 totalAssets = 1; 105 } 106 107 108 @* Theme settings *@ 109 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 110 111 var badgeParms = new Dictionary<string, object>(); 112 badgeParms.Add("size", "h5"); 113 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 114 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 115 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 116 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 117 badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges")); 118 119 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 120 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 121 DateTime createdDate = product.Created.Value; 122 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 123 showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; 124 showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; 125 126 @* Get assets from selected categories or get all assets *@ 127 if (totalAssets != 0) { 128 int assetNumber = 0; 129 int thumbnailNumber = 0; 130 int modalAssetNumber = 0; 131 var assetsListUnique = assetsList.GroupBy(x => x.Value).Select(g => g.First()).ToList(); 132 133 <div class="h-100@(theme) position-relative item_@Model.Item.SystemName.ToLower()"> 134 <div id="SmallScreenImages_@Model.ID" class="carousel@(GetArrowsColor())" data-bs-ride="carousel"> 135 <div class="carousel-inner h-100"> 136 @foreach (MediaViewModel asset in assetsListUnique) { 137 var assetValue = asset.Value; 138 foreach (string format in allSupportedFormats) { 139 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { 140 string activeSlide = assetNumber == 0 ? "active" : ""; 141 142 <div class="carousel-item @activeSlide" data-bs-interval="99999"> 143 144 @{ 145 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 146 string size = "mobile"; 147 148 <div class="h-100 @(imageTheme)"> 149 @foreach (string imageFormat in supportedImageFormats) { //Images 150 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { 151 152 if (product is object) 153 { 154 string productName = product.Name; 155 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 156 string imageLinkPath = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 157 158 RatioSettings ratioSettings = GetRatioSettings(size); 159 160 var parms = new Dictionary<string, object>(); 161 parms.Add("alt", productName + asset.Keywords); 162 parms.Add("itemprop", "image"); 163 parms.Add("fullwidth", true); 164 parms.Add("columns", Model.GridRowColumnCount); 165 if (!string.IsNullOrEmpty(asset.DisplayName)) { 166 parms.Add("title", asset.DisplayName); 167 } 168 169 if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") { 170 parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); 171 } else { 172 parms.Add("cssClass", "mw-100 mh-100"); 173 } 174 175 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> 176 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> 177 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 178 </div> 179 </a> 180 } 181 } 182 } 183 @foreach (string imageFormat in supportedVideoFormats) { //Videos 184 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { 185 if (Model.Item.GetString("OpenVideoInModal") == "true") { 186 187 188 if (product is object) 189 { 190 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 191 192 string videoScreendumpPath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : ""; 193 string videoId = videoScreendumpPath.Substring(videoScreendumpPath.LastIndexOf('/') + 1); 194 videoScreendumpPath = videoScreendumpPath.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || videoScreendumpPath.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "https://img.youtube.com/vi/" + videoId + "/maxresdefault.jpg" : videoScreendumpPath; 195 196 string vimeoJsClass = videoScreendumpPath.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "js-vimeo-video-thumbnail" : ""; 197 videoScreendumpPath = videoScreendumpPath.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "" : videoScreendumpPath; 198 199 string productName = product.Name; 200 productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 201 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; 202 203 RatioSettings ratioSettings = GetRatioSettings(size); 204 205 <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> 206 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> 207 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 208 @if (videoScreendumpPath.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0) 209 { 210 <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@productName" @assetTitle class="@vimeoJsClass mw-100 mh-100" data-video-id="@videoId" style="object-fit: cover;" onload="CheckIfVideoThumbnailExist(this)"> 211 } 212 else 213 { 214 string videoType = Path.GetExtension(asset.Value).ToLower(); 215 216 <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> 217 <source src="@asset.Value" type="video/@videoType.Replace(".", "")"> 218 </video> 219 } 220 </div> 221 </div> 222 223 <script> 224 function CheckIfVideoThumbnailExist(image) { 225 if (image.width == 120) { 226 const lowQualityImage = "https://img.youtube.com/vi/@(videoId)/hqdefault.jpg" 227 image.src = lowQualityImage; 228 } 229 } 230 </script> 231 } 232 } else { 233 if (product is object) 234 { 235 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; 236 string videoId = asset.Value.Substring(asset.Value.LastIndexOf('/') + 1); 237 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : ""; 238 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; 239 type = assetValue.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf(".webm", StringComparison.OrdinalIgnoreCase) >= 0 ? "selfhosted" : type; 240 241 string openInModal = Model.Item.GetString("OpenVideoInModal"); 242 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); 243 244 <div class="h-100" itemscope itemtype="https://schema.org/VideoObject"> 245 <span class="visually-hidden" itemprop="name">@assetName</span> 246 <span class="visually-hidden" itemprop="contentUrl">@asset.Value</span> 247 <span class="visually-hidden" itemprop="thumbnailUrl">@asset.Value</span> 248 249 @if (type != "selfhosted") 250 { 251 <div 252 id="player_@(Pageview.CurrentParagraph.ID)_@(videoId)_@size" 253 class="plyr__video-embed" 254 data-plyr-provider="@(type)" 255 data-plyr-embed-id="@videoId" 256 style="--plyr-color-main: var(--swift-foreground-color); height: 100%"> 257 </div> 258 259 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 260 261 <script type="module"> 262 var player = new Plyr('#player_@(Pageview.CurrentParagraph.ID)_@(videoId)_@size', { 263 type: 'video', 264 youtube: { 265 noCookie: true, 266 showinfo: 0 267 }, 268 fullscreen: { 269 enabled: true, 270 iosNative: true, 271 } 272 }); 273 274 @if (autoPlay && openInModal == "false") 275 { 276 <text> 277 player.config.autoplay = true; 278 player.config.muted = true; 279 player.config.volume = 0; 280 player.media.loop = true; 281 282 player.on('ready', function() { 283 if (player.config.autoplay === true) { 284 player.media.play(); 285 } 286 }); 287 </text> 288 } 289 290 @if (openInModal == "true") 291 { 292 <text> 293 var productDetailsGalleryModal = document.querySelector('#modal_@Model.ID') 294 productDetailsGalleryModal.addEventListener('hidden.bs.modal', function (event) { 295 player.media.pause(); 296 }) 297 </text> 298 } 299 </script> 300 } 301 else 302 { 303 string autoPlayAttributes = (autoPlay && openInModal == "false") ? "loop autoplay muted playsinline" : ""; 304 string videoType = Path.GetExtension(assetValue).ToLower(); 305 306 <video preload="auto" @autoPlayAttributes class="h-100 w-100" style="object-fit: cover;" controls> 307 <source src="@assetValue" type="video/@videoType.Replace(".", "")"> 308 </video> 309 } 310 </div> 311 } 312 } 313 } 314 } 315 @foreach (string imageFormat in supportedDocumentFormats) { //Documents 316 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { 317 if (product is object) 318 { 319 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 320 321 string productName = product.Name; 322 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 323 string imageLinkPath = imagePath; 324 325 RatioSettings ratioSettings = GetRatioSettings(size); 326 327 var parms = new Dictionary<string, object>(); 328 parms.Add("alt", productName + asset.Keywords); 329 parms.Add("itemprop", "image"); 330 parms.Add("fullwidth", true); 331 parms.Add("columns", Model.GridRowColumnCount); 332 if (!string.IsNullOrEmpty(asset.DisplayName)) { 333 parms.Add("title", asset.DisplayName); 334 } 335 336 if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") { 337 parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); 338 } else { 339 parms.Add("cssClass", "mw-100 mh-100"); 340 } 341 342 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@Translate("Download")"> 343 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 344 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> 345 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) { 346 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 347 } 348 </div> 349 </a> 350 } 351 } 352 } 353 </div> 354 } 355 356 357 </div> 358 assetNumber++; 359 } 360 } 361 } 362 </div> 363 </div> 364 365 @if (totalAssets > 1) { 366 <div id="SmallScreenImagesThumbnails_@Model.ID" class="grid grid-10 gap-2 overflow-x-auto my-3"> 367 @foreach (MediaViewModel asset in assetsListUnique) { 368 var assetValue = asset.Value; 369 foreach (string format in allSupportedFormats) { 370 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { 371 string imagePath = Dynamicweb.Context.Current.Server.UrlEncode(assetValue); 372 imagePath = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "https://img.youtube.com/vi/" + assetValue.Substring(assetValue.LastIndexOf('/') + 1) + "/mqdefault.jpg" : imagePath; 373 string imagePathThumb = imagePath.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) < 0 && imagePath.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0 ? $"/Admin/Public/GetImage.ashx?image={imagePath}&width=180&format=webp" : imagePath; 374 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 375 376 string videoId = assetValue.Substring(assetValue.LastIndexOf('/') + 1); 377 string vimeoJsClass = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "js-vimeo-video-thumbnail" : ""; 378 379 bool isDocument = false; 380 foreach (string documentFormat in supportedDocumentFormats) { 381 if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) { 382 isDocument = true; 383 } 384 } 385 386 string assetName = asset.Name; 387 assetName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 388 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; 389 390 if (!isDocument) { 391 RatioSettings ratioSettings = GetRatioSettings("desktop"); 392 393 <div class="border outline-none @(ratioSettings.CssClass)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to="@thumbnailNumber"> 394 <div class="d-flex align-items-center justify-content-center overflow-hidden position-absolute h-100"> 395 @foreach (string videoFormat in supportedVideoFormats) { //Videos 396 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) { 397 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 398 } 399 } 400 </div> 401 @if (imagePathThumb.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0) { 402 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 @vimeoJsClass w-100 h-100" style="object-fit: contain" data-video-id="@videoId"> 403 } else { 404 string videoType = Path.GetExtension(asset.Value).ToLower(); 405 406 <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> 407 <source src="@imagePathThumb" type="video/@videoType.Replace(".", "")"> 408 </video> 409 } 410 </div> 411 } else { 412 <a href="@assetValue" class="ratio ratio-4x3 border outline-none" style="cursor: pointer" download title="@asset.Value"> 413 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) { 414 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 415 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> 416 </div> 417 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 mw-100 mh-100" style="object-fit: cover;"> 418 } else { 419 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 420 <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> 421 </div> 422 } 423 </a> 424 } 425 426 thumbnailNumber++; 427 } 428 } 429 } 430 </div> 431 } 432 433 @if (showBadges) { 434 <div class="position-absolute top-0 left-0 p-2 p-lg-3"> 435 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 436 </div> 437 } 438 </div> 439 440 @* Modal with slides *@ 441 <div class="modal fade swift_products-details-images-modal" id="modal_@Model.ID" tabindex="-1" aria-labelledby="productDetailsGalleryModalTitle_@Model.ID" aria-hidden="true"> 442 <div class="modal-dialog modal-dialog-centered modal-xl"> 443 <div class="modal-content"> 444 <div class="modal-header visually-hidden"> 445 <strong class="modal-title" id="productDetailsGalleryModalTitle_@Model.ID">@product.Title</strong> 446 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 447 </div> 448 <div class="modal-body p-2 p-lg-3 h-100"> 449 <div id="ModalCarousel_@Model.ID" class="carousel@(GetArrowsColor()) h-100" data-bs-ride="carousel"> 450 <div class="carousel-inner h-100"> 451 @foreach (MediaViewModel asset in assetsList) { 452 var assetValue = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 453 foreach (string format in supportedImageFormats.Concat(supportedVideoFormats).ToArray()) { 454 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { 455 string imagePath = assetValue; 456 string activeSlide = modalAssetNumber == 0 ? "active" : ""; 457 458 var parms = new Dictionary<string, object>(); 459 parms.Add("cssClass", "d-block mw-100 mh-100 m-auto"); 460 parms.Add("fullwidth", true); 461 parms.Add("columns", Model.GridRowColumnCount); 462 463 <div class="carousel-item @activeSlide h-100" data-bs-interval="99999"> 464 @foreach (string imageFormat in supportedImageFormats) { //Images 465 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { 466 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 467 } 468 } 469 470 @foreach (string videoFormat in supportedVideoFormats) { //Videos 471 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) { 472 if (product is object) 473 { 474 string size = "modal"; 475 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; 476 string videoId = asset.Value.Substring(asset.Value.LastIndexOf('/') + 1); 477 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : ""; 478 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; 479 type = assetValue.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf(".webm", StringComparison.OrdinalIgnoreCase) >= 0 ? "selfhosted" : type; 480 481 string openInModal = Model.Item.GetString("OpenVideoInModal"); 482 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); 483 484 <div class="h-100" itemscope itemtype="https://schema.org/VideoObject"> 485 <span class="visually-hidden" itemprop="name">@assetName</span> 486 <span class="visually-hidden" itemprop="contentUrl">@asset.Value</span> 487 <span class="visually-hidden" itemprop="thumbnailUrl">@asset.Value</span> 488 489 @if (type != "selfhosted") 490 { 491 <div 492 id="player_@(Pageview.CurrentParagraph.ID)_@(videoId)_@size" 493 class="plyr__video-embed" 494 data-plyr-provider="@(type)" 495 data-plyr-embed-id="@videoId" 496 style="--plyr-color-main: var(--swift-foreground-color); height: 100%"> 497 </div> 498 499 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 500 501 <script type="module"> 502 var player = new Plyr('#player_@(Pageview.CurrentParagraph.ID)_@(videoId)_@size', { 503 type: 'video', 504 youtube: { 505 noCookie: true, 506 showinfo: 0 507 }, 508 fullscreen: { 509 enabled: true, 510 iosNative: true, 511 } 512 }); 513 514 @if (autoPlay && openInModal == "false") 515 { 516 <text> 517 player.config.autoplay = true; 518 player.config.muted = true; 519 player.config.volume = 0; 520 player.media.loop = true; 521 522 player.on('ready', function() { 523 if (player.config.autoplay === true) { 524 player.media.play(); 525 } 526 }); 527 </text> 528 } 529 530 @if (openInModal == "true") 531 { 532 <text> 533 var productDetailsGalleryModal = document.querySelector('#modal_@Model.ID') 534 productDetailsGalleryModal.addEventListener('hidden.bs.modal', function (event) { 535 player.media.pause(); 536 }) 537 </text> 538 } 539 </script> 540 } 541 else 542 { 543 string autoPlayAttributes = (autoPlay && openInModal == "false") ? "loop autoplay muted playsinline" : ""; 544 string videoType = Path.GetExtension(assetValue).ToLower(); 545 546 <video preload="auto" @autoPlayAttributes class="h-100 w-100" style="object-fit: cover;" controls> 547 <source src="@assetValue" type="video/@videoType.Replace(".", "")"> 548 </video> 549 } 550 </div> 551 } 552 } 553 } 554 </div> 555 556 modalAssetNumber++; 557 } 558 } 559 } 560 <button class="carousel-control-prev" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="prev"> 561 <span class="carousel-control-prev-icon" aria-hidden="true"></span> 562 <span class="visually-hidden">@Translate("Previous")</span> 563 </button> 564 <button class="carousel-control-next" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="next"> 565 <span class="carousel-control-next-icon" aria-hidden="true"></span> 566 <span class="visually-hidden">@Translate("Next")</span> 567 </button> 568 </div> 569 </div> 570 </div> 571 </div> 572 </div> 573 </div> 574 } else if (Pageview.IsVisualEditorMode) { 575 RatioSettings ratioSettings = GetRatioSettings("desktop"); 576 577 <div class="h-100 @theme"> 578 <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> 579 <img src="/Files/Images/missing_image.jpg" loading="lazy" decoding="async" class="mh-100 mw-100" style="object-fit: cover;"> 580 </div> 581 </div> 582 } 583 } else if (Pageview.IsVisualEditorMode) { 584 <div class="alert alert-dark m-0">@Translate("No products available")</div> 585 } 586 587 588 589 590 591

XLOCK-Gateway für Schlüsselkasten

1650000013
Artikelnummer des Herstellers
XL-G2/XL-NTUSB

Holen Sie sich mit diesem Gateway Ihren Schlüsselkasten online und öffnen Sie ihn überall auf der Welt.

Geeignet für USB

Error executing template "Designs/Swift/Paragraph/Swift_ProductPrice.cshtml"
System.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   at System.Data.SqlClient.SqlDataReader.Read()
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetAllProductKeys(String productLanguageId)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountInfoCollection.LoadDiscounts()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__40()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__42()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo)
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__43()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at CompiledRazorTemplates.Dynamic.RazorEngine_219ad7bd7a4849b7846ced47383820b6.Execute() in D:\dynamicweb.net\Solutions\Flex Media\danzafe.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\Paragraph\Swift_ProductPrice.cshtml:line 31
   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()
ClientConnectionId:c84949f9-9318-4377-9bbd-599ce5ed4a84
Error Number:1205,State:52,Class:13

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.Prices 4 5 @{ 6 ProductViewModel product = null; 7 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 8 { 9 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 10 } 11 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 12 { 13 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 14 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 15 16 if (productList?.Products is object) 17 { 18 product = productList.Products[0]; 19 } 20 } 21 22 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 23 bool anonymousUser = Pageview.User == null; 24 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 25 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 26 27 bool productIsDiscontinued = product is object && product.Discontinued; 28 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 29 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 30 31 string CurrencyTag = "<span class=\"CurrencyCode\">" + product.Price.CurrencyCode + "</span> "; 32 33 } 34 35 @if (product is object && !hidePrice && !isDiscontinued) { 36 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 37 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 38 39 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2"); 40 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 41 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 42 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 43 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 44 45 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 46 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 47 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 48 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 49 50 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 51 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 52 string order = layout == "horizontal" ? string.Empty : "order-2"; 53 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 54 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme; 55 56 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 57 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 58 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 59 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 60 61 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 62 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 63 64 string priceMin = ""; 65 string priceMax = ""; 66 67 string liveInfoClass = ""; 68 string productInfoFeed = ""; 69 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 70 if (isLazyLoadingForProductInfoEnabled) 71 { 72 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 73 { 74 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 75 if (!string.IsNullOrEmpty(productInfoFeed)) 76 { 77 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 78 } 79 } 80 liveInfoClass = "js-live-info"; 81 } 82 83 84 // var priceContext = new PriceContext(Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(), Dynamicweb.Ecommerce.Services.Countries.GetCountries().FirstOrDefault(), Dynamicweb.Ecommerce.Services.Shops.GetDefaultShop(), null, false, DateTime.Now); 85 86 87 double discountPriceMinD = 0; 88 double discountPriceMaxD = 0; 89 string discountPriceMin = ""; 90 string discountPriceMax = ""; 91 92 // var productCombinationList = new List<ProductViewModel>(); 93 var productVariants = product.VariantCombinations(); 94 var priceContext = new PriceContext(Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(), Dynamicweb.Ecommerce.Services.Countries.GetCountries().FirstOrDefault(), Dynamicweb.Ecommerce.Services.Shops.GetDefaultShop(), Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser(), false, DateTime.Now); 95 96 foreach (var variant in productVariants){ 97 var productVariant = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, variant, true); 98 double VariantDiscountD = productVariant.GetDiscountMatrix(priceContext, product.DefaultUnitId, 1).Price.Price; 99 // string VariantDiscount = productVariant.GetDiscountMatrix(priceContext, product.DefaultUnitId, 1).Price.ToString(); 100 string VariantDiscount = CurrencyTag + productVariant.GetDiscountMatrix(priceContext, product.DefaultUnitId, 1).Price.Price.ToString("#.00"); 101 102 if(VariantDiscountD>0){ 103 if(discountPriceMinD==0 || discountPriceMinD>VariantDiscountD){discountPriceMinD=VariantDiscountD;discountPriceMin=VariantDiscount;} 104 if(discountPriceMaxD==0 || VariantDiscountD>discountPriceMaxD){discountPriceMaxD=VariantDiscountD;discountPriceMax=VariantDiscount;} 105 } 106 } 107 108 109 110 111 112 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 113 @if (showInformativePrice && product.PriceInformative.Price != 0) 114 { 115 <div class="opacity-50"> 116 <span>@Translate("RRP") </span> 117 <span class="text-decoration-line-through text-price">@product.PriceInformative.Price.ToString("#.00")</span> 118 </div> 119 } 120 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 121 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 122 123 124 @if (showPricesWithVat == "false" && !neverShowVat) 125 { 126 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 127 { 128 <span itemprop="price" content="" class="d-none"></span> 129 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> 130 } 131 else 132 { 133 string beforePrice = !string.IsNullOrEmpty(unitId) ? CurrencyTag + product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVat.ToString("#.00") : CurrencyTag + product.PriceBeforeDiscount.PriceWithoutVat.ToString("#.00"); 134 135 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString().Replace(',','.')" class="d-none"></span> 136 if (product.Price.Price != product.PriceBeforeDiscount.Price) 137 { 138 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 139 } 140 } 141 } 142 else 143 { 144 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 145 { 146 <span itemprop="price" content="" class="d-none"></span> 147 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> 148 } 149 else 150 { 151 string beforePrice = !string.IsNullOrEmpty(unitId) ? CurrencyTag + product.GetPrice(unitId).PriceBeforeDiscount.Price.ToString("#.00") : CurrencyTag + product.PriceBeforeDiscount.Price.ToString("#.00"); 152 153 <span itemprop="price" content="@product.Price.Price.ToString().Replace(',','.')" class="d-none"></span> 154 155 if (product.Price.Price != product.PriceBeforeDiscount.Price) 156 { 157 <span class="text-decoration-line-through opacity-75 @order"> 158 <span class="text-price" t=a>@beforePrice</span> 159 </span> 160 } 161 } 162 } 163 164 @if (showPricesWithVat == "false" && !neverShowVat) 165 { 166 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 167 { 168 <span class="text-price js-text-price"> 169 <span class="spinner-border" role="status"></span> 170 </span> 171 } 172 else 173 { 174 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVat.ToString("#.00") : product.Price.PriceWithoutVat.ToString("#.00"); 175 176 if (product?.VariantInfo?.VariantInfo != null) 177 { 178 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVat.ToString("#.00") : ""; 179 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVat.ToString("#.00") : ""; 180 } 181 if (priceMin != priceMax) 182 { 183 price = priceMin + " - " + priceMax; 184 } 185 <span class="@theme @contentPadding"> 186 <span class="text-price" t=b>@price</span> 187 </span> 188 } 189 } 190 else 191 { 192 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 193 { 194 <span class="text-price js-text-price"> 195 <span class="spinner-border" role="status"></span> 196 </span> 197 } 198 else 199 { 200 // string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 201 string price = !string.IsNullOrEmpty(unitId) ? CurrencyTag + product.GetPrice(unitId).Price.Price.ToString("#.00") : CurrencyTag + product.Price.Price.ToString("#.00"); 202 203 double priceD = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.Price : product.Price.Price; 204 double priceMinD= 0; 205 double priceMaxD = 0; 206 if (product?.VariantInfo?.VariantInfo != null) 207 { 208 209 // priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 210 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? CurrencyTag + product.VariantInfo.PriceMin.Price.ToString("#.00") : ""; 211 212 priceMinD = product?.VariantInfo?.PriceMin?.Price != null ? product.VariantInfo.PriceMin.Price : 0; 213 214 // priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 215 priceMax = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? CurrencyTag + product.VariantInfo.PriceMax.Price.ToString("#.00") : ""; 216 217 priceMaxD = product?.VariantInfo?.PriceMax?.Price != null ? product.VariantInfo.PriceMax.Price : 0; 218 } 219 220 if (priceMin != priceMax){ 221 price = priceMin + " - " + priceMax; 222 223 if(priceMinD>discountPriceMinD && priceMaxD>discountPriceMaxD){ 224 price = discountPriceMin + " - " + discountPriceMax; 225 } 226 } 227 if(priceD == 0 && priceMinD > 0 && priceMinD == priceMaxD){ 228 price = priceMin; 229 } 230 231 232 233 <span class="@theme @contentPadding"> 234 <span class="text-price" t=c>@price</span> 235 </span> 236 } 237 } 238 239 @* Stock state for Schema.org, start *@ 240 @{ 241 Uri url = Dynamicweb.Context.Current.Request.Url; 242 } 243 244 <link itemprop="url" href="@url"> 245 246 @{ 247 bool IsNeverOutOfStock = product.NeverOutOfstock; 248 } 249 250 @if (IsNeverOutOfStock) 251 { 252 <span itemprop="availability" class="d-none">InStock</span> 253 <span class="d-none">@Translate("Available in stock")</span> 254 } 255 else 256 { 257 if (product.StockLevel > 0) 258 { 259 <span itemprop="availability" class="d-none">InStock</span> 260 } 261 else 262 { 263 <span itemprop="availability" class="d-none">OutOfStock</span> 264 } 265 } 266 @* Stock state for Schema.org, stop *@ 267 268 </div> 269 270 @if (showPricesWithVat == "false" && !neverShowVat) 271 { 272 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 273 { 274 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 275 } 276 else 277 { 278 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVat.ToString("#.00") : product.Price.PriceWithVat.ToString("#.00"); 279 280 if (product?.VariantInfo?.VariantInfo != null) 281 { 282 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVat.ToString("#.00") : ""; 283 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVat.ToString("#.00") : ""; 284 } 285 if (priceMin != priceMax) 286 { 287 price = priceMin + " - " + priceMax; 288 } 289 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> 290 } 291 } 292 </div> 293 } 294 else if (Pageview.IsVisualEditorMode) 295 { 296 <div class="alert alert-dark m-0" role="alert"> 297 <span>@Translate("No products available")</span> 298 </div> 299 } 300
Error executing template "Designs/Swift/Paragraph/Swift_ProductAddToCart.cshtml"
System.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   at System.Data.SqlClient.SqlDataReader.Read()
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetAllProductKeys(String productLanguageId)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries)
   at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user)
   at Dynamicweb.Ecommerce.Orders.Discounts.DiscountInfoCollection.LoadDiscounts()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__40()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__42()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo)
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__43()
   at System.Lazy`1.CreateValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_1638887c5d86470fa912ccdbda863789.Execute() in D:\dynamicweb.net\Solutions\Flex Media\danzafe.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\Paragraph\Swift_ProductAddToCart.cshtml:line 359
   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()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at CompiledRazorTemplates.Dynamic.RazorEngine_1638887c5d86470fa912ccdbda863789.Execute() in D:\dynamicweb.net\Solutions\Flex Media\danzafe.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\Paragraph\Swift_ProductAddToCart.cshtml:line 359
   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()
ClientConnectionId:c84949f9-9318-4377-9bbd-599ce5ed4a84
Error Number:1205,State:52,Class:13

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 4 @* 5 @using Dynamicweb.Ecommerce.Stocks 6 @using Dynamicweb.Ecommerce.Products 7 @using Dynamicweb.Ecommerce 8 *@ 9 10 @using Dynamicweb.Core.Encoders 11 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 12 13 @using System.Linq 14 @using Dynamicweb.Core 15 @using Dynamicweb.Environment 16 17 18 19 @{ 20 bool isDetailPage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")); 21 ProductViewModel product = null; 22 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 23 { 24 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 25 } 26 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 27 { 28 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 29 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 30 31 if (productList?.Products is object) 32 { 33 product = productList.Products[0]; 34 } 35 } 36 37 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 38 bool anonymousUser = Pageview.User == null; 39 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 40 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 41 hideAddToCart = Pageview.IsVisualEditorMode ? false : hideAddToCart; 42 } 43 44 45 46 @if (product is object && !hideAddToCart) { 47 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 48 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign; 49 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign; 50 horizontalAlign = horizontalAlign == "full" ? "" : horizontalAlign; 51 52 bool favoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 53 bool quantitySelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowQuantitySelector")) ? Model.Item.GetBoolean("ShowQuantitySelector") : false; 54 bool unitsSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowUnitsSelector")) ? Model.Item.GetBoolean("ShowUnitsSelector") : false; 55 bool hideInventory = !string.IsNullOrEmpty(Model.Item.GetString("HideInventory")) ? Model.Item.GetBoolean("HideInventory") : false; 56 bool hideStockState = !string.IsNullOrEmpty(Model.Item.GetString("HideStockState")) ? Model.Item.GetBoolean("HideStockState") : false; 57 58 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 59 string inputSize = string.Empty; 60 61 Dictionary<string, FieldValueViewModel> fields = product.ProductFields; 62 63 64 switch (buttonSize) 65 { 66 case "small": 67 inputSize = " input-group-sm"; 68 buttonSize = " btn-sm"; 69 break; 70 case "regular": 71 buttonSize = string.Empty; 72 break; 73 case "large": 74 inputSize = " input-group-lg"; 75 buttonSize = " btn-lg"; 76 break; 77 } 78 79 string iconPath = "/Files/icons/"; 80 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 81 if (!url.Contains("LayoutTemplate")) 82 { 83 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 84 } 85 86 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 87 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 88 bool isNeverOutOfStock = product.NeverOutOfstock; 89 disableAddToCart = isNeverOutOfStock && !isLazyLoadingForProductInfoEnabled ? "" : disableAddToCart; 90 91 string whenVariantsExist = Model.Item.GetRawValueString("WhenVariantsExist", "hide"); 92 93 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 94 string fullWidth = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "w-100" : ""; 95 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 96 string addToCartLabel = !addToCartIcon.Contains("_none") ? $"<span class=\"icon-2\">{ReadFile(addToCartIcon)}</span>" : ""; 97 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 98 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>" : ""; 99 100 101 string Surface = ""; 102 string hasLockKeyCode = ""; 103 bool KeyCutField = false; 104 foreach (var field in fields) { 105 if (field.Value.SystemName == "HasLockKeyCode"){ 106 hasLockKeyCode = field.Value?.Value != null ? field.Value.Value.ToString() : ""; 107 } 108 if (field.Value.SystemName == "KeyCutField"){ 109 string KeyCutField_string = field.Value?.Value != null ? field.Value.Value.ToString() : ""; 110 if(KeyCutField_string=="True"){KeyCutField = true;} 111 } 112 if (field.Value.SystemName == "Surface"){ 113 Surface = field.Value?.Value != null ? field.Value.Value.ToString() : ""; 114 } 115 } 116 117 118 if ((product.VariantInfo.VariantInfo == null || whenVariantsExist == "disable") && isDetailPage) { 119 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : product.DefaultUnitId; 120 if (string.IsNullOrEmpty(unitId) && product?.UnitOptions != null) { 121 if (product.UnitOptions.FirstOrDefault<UnitOptionViewModel>() != null) { 122 unitId = product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Id; 123 } 124 } 125 126 127 128 // Flex 129 130 131 // IEnumerable<StockLocation> stockLocations = Services.StockService.GetStockLocations(); 132 133 double StockWebshop = 0; 134 double StockSupplier = 0; 135 var stockUnits = Dynamicweb.Ecommerce.Services.StockService.GetStockUnits(product.Id, product.VariantId).ToList(); 136 if (stockUnits.Any()) 137 { 138 var webShopStockUnit = stockUnits.FirstOrDefault(su => su.StockLocationId == 1); 139 if (webShopStockUnit != null) 140 { 141 StockWebshop = webShopStockUnit.StockQuantity; 142 143 } 144 var supplierStockUnit = stockUnits.FirstOrDefault(su => su.StockLocationId == 2); 145 if (supplierStockUnit != null) 146 { 147 StockSupplier = supplierStockUnit.StockQuantity; 148 } 149 } 150 151 double? unitStockLevel = 0; 152 153 bool HasStock = false; 154 foreach (var unitOption in product.UnitOptions){ 155 if (unitOption.StockLevel > 0){ 156 unitStockLevel = unitOption.StockLevel; 157 HasStock = true; 158 } 159 } 160 161 if (StockWebshop > 0){ 162 HasStock = true; 163 } else if (StockSupplier > 0){ 164 HasStock = true; 165 } 166 167 168 disableAddToCart = HasStock && !isLazyLoadingForProductInfoEnabled ? "" : disableAddToCart; 169 170 string minQty = product.PurchaseMinimumQuantity != 1 ? $"min=\"{product.PurchaseMinimumQuantity.ToString()}\"" : "min=\"1\""; 171 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 172 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 173 disableAddToCart = product.VariantInfo.VariantInfo != null && string.IsNullOrEmpty(product.VariantId) ? "disabled" : disableAddToCart; 174 disableAddToCart = product.Discontinued && !product.NeverOutOfstock && !HasStock ? "disabled" : disableAddToCart; 175 176 177 178 179 180 <small style="display: none;">product.Id:@product.Id product.VariantId:@product.VariantId StockWebshop:@StockWebshop HasStock:@HasStock disableAddToCart:@disableAddToCart product.StockLevel:@product.StockLevel unitStockLevel:@unitStockLevel</small> 181 182 183 // <small>@product.StockLevel</small> 184 // <small>@HasStock . @product.Discontinued . @product.NeverOutOfstock = @disableAddToCart </small> 185 // <small>@product.VariantInfo.VariantInfo</small> 186 // <small>@isDetailPage</small> 187 188 bool needKey = false; 189 string KeyGroupID = ""; 190 string KeyList = ""; 191 string DefaultKey = ""; 192 string ReCodeList = ""; 193 string DefaultReCode = ""; 194 string KeyId = ""; 195 string KeyName = ""; 196 string KeyPrice = ""; 197 string keyCode = ""; 198 string KeyWay = ""; 199 string KeyWayType = ""; 200 bool hasKeyWayNew = false; 201 // bool hasKeyWayInCart = false; //.. 202 bool hasKeyInCart = false; 203 bool hasKeyWithCodeInCart = false; 204 205 206 207 foreach (var Groups in product.Groups){ 208 // <small>@Groups.Id</small> 209 if(string.IsNullOrEmpty(KeyGroupID)){ 210 string HasKeyId = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(Groups.Id)?.ProductGroupFieldValues.FirstOrDefault(f => f.ProductGroupField.SystemName == "KeyProductIds")?.Value.ToString(); 211 string HasReCodeId = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(Groups.Id)?.ProductGroupFieldValues.FirstOrDefault(f => f.ProductGroupField.SystemName == "ReCodeProductIds")?.Value.ToString(); 212 if(!string.IsNullOrEmpty(HasKeyId) || !string.IsNullOrEmpty(HasReCodeId)){ 213 KeyGroupID = Groups.Id; 214 } 215 } 216 } 217 218 219 if(!string.IsNullOrEmpty(KeyGroupID)){ 220 KeyList = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(KeyGroupID)?.ProductGroupFieldValues.FirstOrDefault(f => f.ProductGroupField.SystemName == "KeyProductIds")?.Value.ToString(); 221 ReCodeList = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(KeyGroupID)?.ProductGroupFieldValues.FirstOrDefault(f => f.ProductGroupField.SystemName == "ReCodeProductIds")?.Value.ToString(); 222 KeyWayType = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(KeyGroupID)?.ProductGroupFieldValues.FirstOrDefault(f => f.ProductGroupField.SystemName == "KeyWayType")?.Value.ToString(); 223 } 224 List<string> KeyCodes = new List<string>(); 225 string[] Keys = KeyList.Split(','); 226 DefaultKey = Keys[0]; 227 List<string> ReCodes = new List<string> 228 (); 229 string[] ReCode = ReCodeList.Split(','); 230 DefaultReCode = ReCode[0]; 231 232 if((KeyList.Length>0 || ReCodeList.Length>0) && isDetailPage && !KeyCutField){needKey = true;} 233 234 // else{hasLockKeyCode="";} 235 236 237 // <small>bob @needKey</small> 238 // <small>@KeyList.Length @ReCodeList.Length @KeyWayType.Length</small> 239 // <small><strong>@DefaultKey</strong></small> 240 241 // finding keycode in cart 242 if(needKey || KeyCutField){ 243 if (Dynamicweb.Ecommerce.Common.Context.Cart != null) { 244 var CartList = Dynamicweb.Ecommerce.Common.Context.Cart.OrderLines; 245 foreach (var Orderline in CartList){ 246 bool matchKey = false; 247 if(Orderline.OrderLineFieldValues.Count>0){ 248 var KeyWayObj = Orderline.OrderLineFieldValues.FirstOrDefault(fv => fv.OrderLineFieldSystemName == "KeyWayType"); 249 if(!string.IsNullOrEmpty(KeyWayObj?.Value)){KeyWay = KeyWayObj.Value;}else{KeyWay="";} 250 var keyCodeObj = Orderline.OrderLineFieldValues.FirstOrDefault(fv => fv.OrderLineFieldSystemName == "LockKeyCode"); 251 if(!string.IsNullOrEmpty(keyCodeObj?.Value)){keyCode = keyCodeObj.Value;}else{keyCode="";} 252 253 if(KeyWayType==KeyWay){ 254 matchKey = true; 255 } 256 257 } 258 foreach (var Fields in Orderline.Product.OrderLineFields){ 259 if(Fields.SystemName=="LockKeyCode" && matchKey){ 260 bool isNew = true; 261 foreach(string K in KeyCodes){if(K==keyCode){isNew=false;}} 262 if(!string.IsNullOrEmpty(keyCode) && isNew){KeyCodes.Add(keyCode);} 263 if(string.IsNullOrEmpty(keyCode)){hasKeyWayNew=true;} 264 } 265 } 266 // finding keycode in cart - end 267 268 foreach (var Key in Keys){ 269 if(Key == Orderline.ProductId && matchKey){ 270 hasKeyInCart = true; 271 if(!string.IsNullOrEmpty(keyCode)){ 272 hasKeyWithCodeInCart = true; 273 } 274 } 275 } 276 277 278 279 280 // foreach (var Fields in Orderline.Product.OrderLineFields){ 281 // if(Fields.SystemName == "KeyWayType" && matchKey){ 282 // <small style="font-size:.6em;">@Orderline.Id @Fields.Name @KeyWayType @keyCode<br/></small> 283 // } 284 // } 285 286 } 287 } 288 } 289 290 291 292 if(needKey || KeyCutField){ // options from cart 293 <datalist id="knowenkeys"> 294 @if(hasKeyWayNew){<option value="">Leave blank to match one in cart</option>} 295 @foreach(string c in KeyCodes){<option value="@c">@c</option>} 296 </datalist> 297 } 298 299 300 if(needKey && 1==2){ // test 301 <div style="position:relative; z-index:10;"> 302 <div style="font-size:.7em;color:#aaa;"> 303 <small>KeyCutField: @KeyCutField<br /></small> 304 <small>hasLockKeyCode: @hasLockKeyCode<br /></small> 305 <small>need key: @needKey <br/></small> 306 <small>key in cart: @hasKeyInCart <br/></small> 307 <small>key w code in cart: @hasKeyWithCodeInCart</small> 308 </div> 309 </div> 310 } 311 312 313 314 315 if(needKey && 1==2){ // select options 316 <div class="mt-1 mb-1" style="position:relative; z-index:10;"> 317 @* <label>temp: for adding to cart if recode</label>*@ 318 <select style="font-size: 0.66em;"> 319 320 321 @foreach (var Key in Keys){ 322 var KeyProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(Key,"", product.LanguageId); 323 324 if(KeyProduct != null){ 325 KeyId = KeyProduct.Id.ToString(); 326 KeyName = KeyProduct.Name.ToString(); 327 KeyPrice = KeyProduct.Price.ToString(); 328 // something = KeyProduct.ProductFieldValues.GetProductFieldValue("Width").Value.ToString(); 329 } 330 <option value="@KeyId" @if(KeyId==DefaultKey){<text>selected="selected" </text>}>@KeyName @KeyPrice</option> 331 332 // <small><br/>@KeyId @KeyName @KeyPrice </small> 333 334 } 335 336 </select> 337 </div> 338 } 339 340 if(needKey && 1==2){ 341 if (hasLockKeyCode == "True" && whenVariantsExist != "disable"){ 342 <div class="js-stock-state text-center"> 343 <div class="small">@Translate("hasLockKeyCode_text")</div> 344 </div> 345 } 346 } 347 348 349 350 351 var reserveMode = Dynamicweb.Ecommerce.Frontend.Cart.ProductReserve.Mode; 352 353 if (unitsSelector && product.UnitOptions.Count > 0) { 354 <form f=a method="post" action="/Default.aspx?ID=@(Pageview.Page.ID)&ProductId=@product.Id" id="UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID"> 355 <input type="hidden" name="redirect" value="false"> 356 <input type="hidden" name="VariantID" value="@product.VariantId"> 357 <input type="hidden" name="UnitID" class="js-unit-id" value="@unitId"> 358 </form> 359 } 360 361 <div class="d-flex @horizontalAlign @fullWidth js-input-group item_@Model.Item.SystemName.ToLower()"> 362 <form f=b method="post" action="@url" class="@fullWidth" style="z-index: 1"> 363 <input type="hidden" name="redirect" value="false"> 364 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 365 <input type="hidden" name="ProductPrice" value="@PriceViewModelExtensions.ToStringInvariant(product.Price)"> 366 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 367 368 @if(!needKey){ 369 <input type="hidden" name="cartcmd" value="add"> 370 <input type="hidden" name="ProductId" value="@product.Id"> 371 <input type="hidden" name="ProductName" value="@HtmlEncoder.HtmlEncode(product.Name)"> 372 <input type="hidden" name="VariantID" value="@product.VariantId"> 373 <input type="hidden" name="ProductVariantName" value="@product.VariantName"> 374 <input id="@(product.Id)_StockLocationId" type="hidden" name="StockLocationId" value=""> 375 if (quantitySelector || (!anonymousUser && product.VariantInfo.VariantInfo != null) || (!anonymousUser && favoritesSelector)) 376 { 377 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId" name="UnitID" value="@unitId" /> 378 } 379 <input type="hidden" name="EcomOrderLineFieldInput_Surface" value="@Surface" /> 380 381 } 382 @if(needKey){ 383 <input name="cartcmd" value="addmulti" type="hidden" /> 384 <input type="hidden" name="ProductLoopCounter1" value="1" /> 385 <input type="hidden" name="ProductId1" value="@product.Id" /> 386 <input type="hidden" name="ProductName1" value="@product.Name" /> 387 <input type="hidden" name="VariantID1" value="@product.VariantId"> 388 <input type="hidden" name="ProductVariantName1" value="@product.VariantName" /> 389 <input id="@(product.Id)_StockLocationId" type="hidden" name="StockLocationId1" value="" /> 390 391 if (!string.IsNullOrEmpty(KeyWayType)){ 392 <input type="hidden" name="EcomOrderLineFieldInput_KeyWayType1" value="@KeyWayType" /> 393 } 394 if (quantitySelector || (!anonymousUser && product.VariantInfo.VariantInfo != null) || (!anonymousUser && favoritesSelector)) 395 { 396 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId" name="UnitID1" value="@unitId" /> 397 } 398 <input type="hidden" name="EcomOrderLineFieldInput_Surface1" value="@Surface" /> 399 400 401 402 403 <input type="hidden" name="ProductLoopCounter2" value="2" /> 404 <input type="hidden" name="ProductId2" value="@DefaultReCode" /> 405 <input id="Quantity2" type="hidden" name="Quantity2" value="1" disabled="" /> 406 <input type="hidden" name="EcomOrderLineFieldInput_ForProductId2" value="@product.Id" /> 407 <input type="hidden" name="EcomOrderLineFieldInput_ForProductVariantId2" value="@product.VariantId" /> 408 <input type="hidden" name="EcomOrderLineFieldInput_KeyWayType2" value="@KeyWayType" /> 409 <input type="hidden" name="EcomOrderLineFieldInput_LockKeyCode2" id="EcomOrderLineFieldInput_LockKeyCode2" value="" /> 410 411 <input type="hidden" name="ProductLoopCounter3" value="3" /> 412 <input type="hidden" name="ProductId3" value="@DefaultKey" /> 413 <input id="Quantity3" type="hidden" name="Quantity3" value="1" disabled="" /> 414 <input type="hidden" name="EcomOrderLineFieldInput_IsCodeKey3" value="True" /> 415 <input type="hidden" name="EcomOrderLineFieldInput_ForProductId3" value="@product.Id" /> 416 <input type="hidden" name="EcomOrderLineFieldInput_ForProductVariantId3" value="@product.VariantId" /> 417 <input type="hidden" name="EcomOrderLineFieldInput_KeyWayType3" value="@KeyWayType" /> 418 <input type="hidden" name="EcomOrderLineFieldInput_LockKeyCode3" id="EcomOrderLineFieldInput_LockKeyCode3" value="" /> 419 420 } 421 422 423 424 425 @if (reserveMode == Dynamicweb.Ecommerce.Frontend.Cart.ProductReserveMode.AddToCart) 426 { 427 <input type="hidden" name="GetReservedAmount" value="true"> 428 } 429 430 @if (!string.IsNullOrEmpty(product.VariantId)) 431 { 432 // <input type="hidden" name="VariantId" value="@product.VariantId"> 433 } 434 435 436 437 438 439 440 @if (!product.NeverOutOfstock) 441 { 442 <input type="hidden" name="Stock" value="@unitStockLevel" u="@unitStockLevel" p="@product.StockLevel" sw="@StockWebshop" > 443 444 <template class="js-out-of-stock-notice"> 445 <div class="modal-header"> 446 <h1 class="modal-title fs-5">@Translate("Stock limit")</h1> 447 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 448 </div> 449 <div class="modal-body"> 450 @Translate("There are not enough products in stock. The product might be sold out or discontinued. Please adjust the quantity.") 451 </div> 452 </template> 453 } 454 455 456 457 458 459 460 461 462 @if (stepQty != "1") 463 { 464 <template class="js-step-quantity-warning"> 465 <div class="modal-header"> 466 <h1 class="modal-title fs-5">@Translate("The quantity is not valid")</h1> 467 </div> 468 <div class="modal-body"> 469 @Translate("Please select a quantity that is dividable by") @stepQty 470 </div> 471 </template> 472 } 473 @if (product.PurchaseMinimumQuantity != 1) 474 { 475 <template class="js-min-quantity-warning"> 476 <div class="modal-header"> 477 <h1 class="modal-title fs-5">@Translate("The product could not be added to the cart")</h1> 478 </div> 479 <div class="modal-body"> 480 @Translate("The quantity is not valid. You must buy at least") @product.PurchaseMinimumQuantity 481 </div> 482 </template> 483 } 484 485 486 <div class="d-flex flex-row w-100"> 487 @if (!quantitySelector) 488 { 489 if(!needKey){ 490 <input id="Quantity_@(product.Id)_@product.VariantId" class="swift_quantity_field" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> 491 } 492 if(needKey){ 493 <input id="Quantity_@(product.Id)_@product.VariantId" class="swift_quantity_field" name="Quantity1" value="@valueQty" type="hidden" @disableAddToCart> 494 } 495 } 496 497 @if (unitsSelector && product.UnitOptions.Count > 0) 498 { 499 string selectedUnitName = !string.IsNullOrEmpty(unitId) && product?.UnitOptions != null ? unitId : product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Name; 500 501 foreach (var unitOption in product.UnitOptions) 502 { 503 if (unitOption.Id == unitId) 504 { 505 selectedUnitName = unitOption.Name; 506 } 507 } 508 509 <div class="d-flex flex-column gap-2 w-100"> 510 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 511 @if (!anonymousUser && favoritesSelector) 512 { 513 @RenderPartial("Components/ToggleFavorite.cshtml", product) 514 } 515 516 @if (quantitySelector) 517 { 518 if(!needKey){ 519 <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> 520 } 521 if(needKey){ 522 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity1" 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> 523 } 524 } 525 526 <button class="btn btn-secondary @flexFill dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 527 @selectedUnitName 528 </button> 529 530 <ul class="dropdown-menu swift_unit-field"> 531 @foreach (var unitOption in product.UnitOptions) 532 { 533 var selectedUnit = unitOption.Id == unitId ? "selected" : ""; 534 535 <li> 536 <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'); 537 document.querySelector('#Unit_@(product.Id)_@product.VariantId').value = this.getAttribute('data-value'); 538 swift.PageUpdater.Update(document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID'))"> 539 <span>@unitOption.Name</span> 540 <span> 541 @if (unitOption.StockLevel > 0) 542 { 543 if (!Model.Item.GetBoolean("HideInventory")) 544 { 545 <span class="small text-success" u=a>@unitOption.StockLevel @Translate("In stock")</span> 546 } 547 else 548 { 549 <span class="small text-success" u=b>@Translate("In stock")</span> 550 } 551 } 552 else 553 { 554 <span class="small text-danger" u=c>@Translate("Out of Stock")</span> 555 } 556 </span> 557 </button> 558 </li> 559 } 560 </ul> 561 </div> 562 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary @(buttonSize) js-add-to-cart-button" style="white-space: nowrap" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> 563 @if (!Model.Item.GetBoolean("HideButtonText")) 564 { 565 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 566 @addToCartLabel 567 </span> 568 } 569 else 570 { 571 @addToCartLabel 572 } 573 </button> 574 </div> 575 } 576 else 577 { 578 if (!anonymousUser && favoritesSelector) 579 { 580 @RenderPartial("Components/ToggleFavorite.cshtml", product) 581 } 582 583 584 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 585 @if (quantitySelector) 586 { 587 if(!needKey){ 588 <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> 589 } 590 if(needKey){ 591 <input id="Quantity1" name="Quantity1" value="@valueQty" step="@stepQty" @minQty class="form-control swift_quantity-field" style="min-width: 60px; max-width: 100px; z-index: 1" type="number" onchange="ReCodeQuantity();swift.Cart.UpdateOnEnterKey(event)" onkeyup="ReCodeQuantity();swift.Cart.UpdateOnEnterKey(event)" @disableAddToCart> 592 } 593 } 594 595 <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="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> 596 @if (!Model.Item.GetBoolean("HideButtonText")) 597 { 598 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 599 @addToCartLabel 600 </span> 601 } 602 else 603 { 604 @addToCartLabel 605 } 606 </button> 607 </div> 608 } 609 </div> 610 611 612 613 @if (hasLockKeyCode == "True" && whenVariantsExist == "disable"){ 614 615 <p>&nbsp;</p> 616 <p><input id="LockKeyCode" name="EcomOrderLineFieldInput_ReCoding1" type="checkbox" value="true" onChange="checkboxElement(this,'KeyCodeSection');" /> <label for="LockKeyCode">@Translate("Ønsker den omkodet")</label></p> 617 618 <div id="KeyCodeSection" class="hide"> 619 @* <small style="font-size: .7em;color: #999;">@DefaultKey @DefaultReCode</small>*@ 620 621 <div class="mt-4 input-group"> 622 <label for="EcomOrderLineFieldInput_LockKeyCode1">@Translate("Ønsker du låsen/låsene kodet til eksisterende system") 623 <br /> 624 <input list="knowenkeys" style="max-width: 26rem;" class="form-control" type="text" name="EcomOrderLineFieldInput_LockKeyCode1" id="EcomOrderLineFieldInput_LockKeyCode1" onchange="matchCartOption(this)" onkeyup="matchCartOption(this)"> 625 </label> 626 627 </div> 628 629 </div> 630 631 <script> 632 function checkboxElement(a,b){ 633 c=document.getElementById(b).classList; 634 if(a.checked){c.remove("hide");}else{c.add("hide");} 635 wantReCode(); 636 } 637 638 function wantReCode(){ 639 a=document.getElementById("LockKeyCode").checked; 640 if(a){document.getElementById("Quantity2").disabled=false; 641 }else{document.getElementById("Quantity2").disabled=true;} 642 // ReCodeQuantity(); 643 matchCartOption(document.getElementById('EcomOrderLineFieldInput_LockKeyCode1')); 644 } 645 646 function matchCartOption(a){ 647 m=false;l=a.getAttribute("list");v=a.value; 648 b=document.getElementById(l).getElementsByTagName("option"); 649 c=document.getElementById("LockKeyCode").checked; 650 document.getElementById("EcomOrderLineFieldInput_LockKeyCode2").value=v; 651 document.getElementById("EcomOrderLineFieldInput_LockKeyCode3").value=v; 652 for(i=0;i<b.length;i++){if(b[i].value==v){m=true;}} 653 if(c && !m){ 654 // if wants recode and no match in cart 655 // enable "add key to cart" 656 document.getElementById("Quantity3").disabled=false; 657 }else{ 658 // disable "add key to cart" 659 document.getElementById("Quantity3").disabled=true; 660 } 661 ReCodeQuantity(); 662 } 663 664 function ReCodeQuantity(){ 665 document.getElementById("Quantity2").value=document.getElementById("Quantity1").value; 666 } 667 668 document.addEventListener("DOMContentLoaded", function(){ 669 checkboxElement(document.getElementById('LockKeyCode'),'KeyCodeSection'); 670 }); 671 672 673 // checkboxElement(document.getElementById('LockKeyCode'),'KeyCodeSection'); 674 // wantReCode(); 675 // ReCodeQuantity(); 676 // matchCartOption(document.getElementById('EcomOrderLineFieldInput_LockKeyCode1')); 677 // alert("bob") 678 679 </script> 680 <style>.hide{display: none;}</style> 681 682 683 } 684 685 686 687 @if (KeyCutField && whenVariantsExist == "disable"){ 688 <div id="KeyCodeSection"> 689 690 <div class="mt-4 input-group"> 691 <label for="EcomOrderLineFieldInput_LockKeyCode">@Translate("Ønsker du nøglen/nøglernerne kodet til eksisterende system") 692 <br /> 693 <input list="knowenkeys" style="max-width: 26rem;" class="form-control" type="text" name="EcomOrderLineFieldInput_LockKeyCode" id="EcomOrderLineFieldInput_LockKeyCode"> 694 <input type="hidden" name="EcomOrderLineFieldInput_KeyWayType" value="@KeyWayType" /> 695 </label> 696 </div> 697 698 </div> 699 700 701 } 702 703 704 705 </form> 706 </div> 707 } else if (whenVariantsExist == "modal") { 708 string buttonText = Translate("Select"); 709 string variantId = !string.IsNullOrWhiteSpace(product.VariantId) ? product.VariantId : product.DefaultVariantId; 710 711 string variantSelectorServicePageId = !string.IsNullOrEmpty(Model.Item.GetString("VariantSelectorServicePageId")) ? Model.Item.GetLink("VariantSelectorServicePageId").PageId.ToString() : ""; 712 variantSelectorServicePageId = variantSelectorServicePageId != "" ? variantSelectorServicePageId : GetPageIdByNavigationTag("VariantSelectorService").ToString(); 713 714 // Flex 715 if (hasLockKeyCode == "True"){ 716 <div class="js-stock-state text-center"> 717 <div class="small">@Translate("hasLockKeyCode_text")</div> 718 </div> 719 } 720 721 722 <div class="d-flex @horizontalAlign w-100 item_@Model.Item.SystemName.ToLower()"> 723 724 725 726 @if (!anonymousUser && favoritesSelector) 727 { 728 @RenderPartial("Components/ToggleFavorite.cshtml", product) 729 } 730 <form f=c action="/Default.aspx?ID=@variantSelectorServicePageId" data-response-target-element="DynamicModalContent" data-preloader="inline" style="z-index: 1" class="@fullWidth"> 731 <input type="hidden" name="ProductID" value="@product.Id"> 732 <input type="hidden" name="VariantID" value="@variantId"> 733 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()"> 734 <input type="hidden" name="HideInventory" value="@hideInventory.ToString()"> 735 <input type="hidden" name="HideStockState" value="@hideStockState.ToString()"> 736 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 737 <input type="hidden" name="ViewType" value="ModalContent"> 738 @if (isLazyLoadingForProductInfoEnabled) 739 { 740 @* If lazy loading is enabled, bypass it because we're loading a modal window, so render everything as if it was server-side *@ 741 <input type="hidden" name="getproductinfo" value="true"> 742 } 743 744 @{ 745 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 746 string googleTagManagerID = Pageview.AreaSettings.GetString("GoogleTagManagerID"); 747 string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); 748 bool allowTracking = true; 749 if (CookieManager.IsCookieManagementActive) 750 { 751 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 752 allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 753 } 754 allowTracking = true; 755 756 string clickProductLink = string.Empty; 757 if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 758 { 759 clickProductLink = "onclick=\"return clickProductLink('" + @product.Id + "', '" + @product.Name + "', '" + @product.VariantName + "', '" + @product.Price.CurrencyCode + "', '" + @product.Price.Price + "')\""; 760 } 761 762 763 764 765 } 766 767 <a type="button" href="@(link)" class="btn btn-primary@(buttonSize) @fullWidth" title="@Translate("Select")" id="OpenVariantSelectorModal@(product.Id)_@Pageview.CurrentParagraph.ID">@buttonText</a> 768 769 770 @*<button type="button" onclick="swift.PageUpdater.Update(event)" class="btn btn-primary@(buttonSize) @fullWidth" title="@Translate("Select")" data-bs-toggle="modal" data-bs-target="#DynamicModal" id="OpenVariantSelectorModal@(product.Id)_@Pageview.CurrentParagraph.ID">@buttonText</button> 771 *@ 772 773 774 775 776 </form> 777 </div> 778 } 779 } else if (Pageview.IsVisualEditorMode) { 780 <div class="alert alert-dark m-0">@Translate("No products available")</div> 781 } 782
2 auf Lager
 


   Schneller Versand für Lagerartikel

   Lieferung per DPD

   Über 120.000 zufriedene Kunden

 


 


 

Spezifikationen

Brand
XLOCK

Verwandte Produkte