Mit Bilvalg Showroom

18 biler

Sortering

Mærke

Biltype Biltype

Error executing template "Designs/Swift/Paragraph/Swift_ProductListListViewCustom.cshtml"
System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.String.System.IConvertible.ToInt32(IFormatProvider provider)
   at CompiledRazorTemplates.Dynamic.RazorEngine_fd3fa3e61a834a66b4f7e90a1e726709.<RenderProductList>b__0_0(TextWriter __razor_helper_writer) in D:\DynamicWeb\Solutions\fleggaard-leasing-dw.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListListViewCustom.cshtml:line 104
   at CompiledRazorTemplates.Dynamic.RazorEngine_fd3fa3e61a834a66b4f7e90a1e726709.Execute() in D:\DynamicWeb\Solutions\fleggaard-leasing-dw.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListListViewCustom.cshtml:line 17
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 5 @{ 6 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 7 } 8 9 @if (!string.IsNullOrEmpty(theme)) 10 { 11 <div class="h-100@(theme)"> 12 @RenderProductList() 13 </div> 14 } 15 else 16 { 17 @RenderProductList() 18 } 19 20 @helper RenderProductList() 21 { 22 ProductListViewModel productList = new ProductListViewModel(); 23 24 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 25 { 26 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 27 } 28 29 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 30 bool anonymousUser = Pageview.User == null; 31 bool hideProductNumber = !string.IsNullOrEmpty(Model.Item.GetString("HideProductNumber")) ? Model.Item.GetBoolean("HideProductNumber") : false; 32 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser; 33 bool hideAddToCart = !string.IsNullOrEmpty(Model.Item.GetString("HideAddToCart")) ? Model.Item.GetBoolean("HideAddToCart") : false; 34 hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser ? true : hideAddToCart; 35 bool hideFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("HideFavoritesSelector")) ? Model.Item.GetBoolean("HideFavoritesSelector") : false; 36 37 string detailsPageLink = Dynamicweb.Context.Current.Items["DetailsPageLink"] != null ? Dynamicweb.Context.Current.Items["DetailsPageLink"].ToString() : ""; 38 string productTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ProductTheme")) ? " theme p-3 " + Model.Item.GetRawValueString("ProductTheme").Replace(" ", "").Trim().ToLower() : ""; 39 string modalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ModalTheme")) ? " theme " + Model.Item.GetRawValueString("ModalTheme").Replace(" ", "").Trim().ToLower() : "theme light"; 40 string textPadding = !string.IsNullOrEmpty(Model.Item.GetString("ContentPadding")) ? Model.Item.GetRawValueString("ContentPadding") : "none"; 41 textPadding = textPadding == "none" ? "" : textPadding; 42 textPadding = textPadding == "small" ? "p-2 p-lg-3" : textPadding; 43 textPadding = textPadding == "large" ? "p-3 p-lg-4" : textPadding; 44 45 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") : ""; 46 string url = Dynamicweb.Context.Current.Request.RawUrl; 47 48 var badgeParms = new Dictionary<string, object>(); 49 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 50 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 51 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 52 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 53 badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges")); 54 55 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 56 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 57 58 var favoriteParameters = new Dictionary<string, object>(); 59 if (!anonymousUser && !hideFavoritesSelector) 60 { 61 int defaultFavoriteListId = 0; 62 63 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 64 if (favoreiteLists.Count() == 1) 65 { 66 foreach (FavoriteList list in favoreiteLists) 67 { 68 defaultFavoriteListId = list.ListId; 69 } 70 } 71 72 favoriteParameters.Add("ListId", defaultFavoriteListId); 73 } 74 75 if (productList.TotalProductsCount > 0) 76 { 77 int pageSizeSetting = 30; 78 int pageSize = productList.PageSize; 79 pageSize += pageSizeSetting; 80 81 int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : productList.PageSize; 82 83 foreach (ProductViewModel product in productList.Products) 84 { 85 var defaultGroupId = product.PrimaryOrDefaultGroup.Id; 86 var selectedDetailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(defaultGroupId)?.Meta.PrimaryPage ?? string.Empty; 87 88 string link = string.IsNullOrEmpty(selectedDetailPage) ? $"{detailsPageLink}&groupid={defaultGroupId}" : selectedDetailPage; 89 link += "&productid=" + product.Id; 90 link += !string.IsNullOrEmpty(product.VariantId) ? "&variantid=" + product.VariantId : ""; 91 92 string imagePath = product?.DefaultImage?.Value ?? ""; 93 imagePath = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 94 imagePath = "/Admin/Public/GetImage.ashx?width=" + 80 + "&image=" + imagePath + "&format=webp"; 95 96 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 97 ratio = ratio != "0" ? ratio : ""; 98 string ratioCssClass = ratio != "" ? " ratio" : ""; 99 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 100 101 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 102 string imageId = "ProductImage_" + product.Id + product.VariantId; 103 104 int carSumTaxBaseAmountDkkToShowPrice = Convert.ToInt32(product.ProductFields["CarSumTaxBaseAmountDkk"].Value); 105 106 @* Alternative image *@ 107 var supportedImageFormats = new string[] { ".jpg", ".webp", ".png", ".gif" }; 108 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 109 var selectedAssetCategories = Model.Item.GetRawValueString("AlternativeImageAssets"); 110 IEnumerable<MediaViewModel> alternativeImagesList = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 111 112 if (alternativeImagesList.FirstOrDefault() != null) 113 { 114 alternativeImagesList = alternativeImagesList.OrderByDescending(x => x.Value.Equals(defaultImage)); 115 116 if (alternativeImagesList.First().Value == defaultImage) 117 { 118 alternativeImagesList = alternativeImagesList.Skip(1); 119 } 120 } 121 122 @* Badges *@ 123 DateTime createdDate = product.Created.Value; 124 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 125 showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; 126 showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; 127 128 string alternativeImage = alternativeImagesList.FirstOrDefault() != null ? alternativeImagesList.FirstOrDefault().Value : ""; 129 alternativeImage = !string.IsNullOrEmpty(alternativeImage) ? "/Admin/Public/GetImage.ashx?width=" + 80 + "&image=" + alternativeImage + "&format=webp" : ""; 130 131 @* Main features *@ 132 IEnumerable<string> selectedDisplayGroups = Model.Item.GetRawValueString("MainFeatures").Split(',').ToList(); 133 List<CategoryFieldViewModel> mainFeatures = new List<CategoryFieldViewModel>(); 134 135 foreach (var selection in selectedDisplayGroups) 136 { 137 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 138 { 139 if (selection == group.Id) 140 { 141 mainFeatures.Add(group); 142 } 143 } 144 } 145 146 <style> 147 .short-description > p:last-child { 148 margin: 0; 149 } 150 </style> 151 152 <article class="grid gap-2 gap-lg-3 mb-3 @(productTheme) @textPadding"> 153 <a href="@link" class="g-col-12 g-col-lg-8 d-flex text-decoration-none mb-2 mb-lg-0"> 154 @if (!Model.Item.GetBoolean("HideImage")) 155 { 156 <div class="d-flex align-items-center me-2 me-lg-3" style="min-width: 80px"> 157 <div class="@ratioCssClass m-0" style="@(ratioVariable)"> 158 <figure class="m-0 d-flex justify-content-center"> 159 <div class="d-flex justify-content-center align-items-center h-100 w-100"> 160 @if (string.IsNullOrEmpty(alternativeImage)) 161 { 162 <img src="@imagePath" alt="@product.Name" class="mw-100 mh-100" loading="lazy" style="object-fit: cover;" /> 163 } 164 else 165 { 166 <img src="@imagePath" onmouseover="this.src='@alternativeImage'" onmouseout="this.src='@imagePath'" alt="@product.Name" class="mw-100 mh-100" loading="lazy" style="object-fit: cover;" /> 167 } 168 </div> 169 </figure> 170 </div> 171 </div> 172 } 173 174 <div class="flex-fill"> 175 <div class="flex-fill d-flex align-items-center gap-2"> 176 <h3 class="h6 mb-0"> 177 @product.Name @if (!string.IsNullOrEmpty(product.VariantName)) 178 {<text>(@product.VariantName)</text>} 179 </h3> 180 181 @if (showBadges) 182 { 183 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 184 } 185 </div> 186 187 @if (!hideProductNumber) 188 { 189 <div class="fs-7 opacity-75">@product.Number</div> 190 } 191 @if (!Model.Item.GetBoolean("HideStockState")) 192 { 193 <div class="g-col-12 fs-7 d-block d-lg-none"> 194 @RenderStockState(product) 195 </div> 196 } 197 @if (!Model.Item.GetBoolean("HideShortDescription") && selectedDisplayGroups.Count() > 0) 198 { 199 <div class="grid gap-2 gap-lg-4 w-100"> 200 <div class="g-col-12 g-col-lg-8 fs-7 fs-7 d-none d-lg-block short-description"> 201 @product.ShortDescription 202 </div> 203 <div class="g-col-12 g-col-lg-4"> 204 @RenderMainFeatures(mainFeatures) 205 </div> 206 </div> 207 } 208 else 209 { 210 if (!Model.Item.GetBoolean("HideShortDescription")) 211 { 212 <div class="fs-7 d-none d-lg-block"> 213 @product.ShortDescription 214 </div> 215 } 216 @RenderMainFeatures(mainFeatures) 217 } 218 </div> 219 </a> 220 221 <div class="g-col-12 g-col-lg-4 d-flex flex-column gap-2 gap-lg-4 align-items-end"> 222 223 @if (!hidePrice) 224 { 225 <div class="text-end align-self-end d-none d-lg-block w-100"> 226 @RenderPrice(product) 227 </div> 228 } 229 @if (hidePrice && carSumTaxBaseAmountDkkToShowPrice>0) 230 { 231 string carSumTaxBaseAmountDkk = Decimal.TryParse(Convert.ToString(product.ProductFields["CarSumTaxBaseAmountDkk"].Value), out decimal result) ? result.ToString("C2") : 0.ToString("C2"); 232 string carSumTaxBaseAmountDkkMth = Decimal.TryParse(Convert.ToString(product.ProductFields["CarSumTaxBaseAmountMthDkk"].Value), out decimal result2) ? result2.ToString("C2") : 0.ToString("C2"); 233 234 <div class="clearfix g-col-12 text-black-50"> 235 <span class="text-wrap">@Translate("Tax base"):</span> 236 <span class="text-price float-sm-end"> 237 @carSumTaxBaseAmountDkk 238 </span> 239 </div> 240 241 <div class="clearfix g-col-12 text-black-50"> 242 <span class="text-wrap"> 243 @Translate("Monthly tax"): 244 </span> 245 <span class="text-price float-sm-end"> 246 @carSumTaxBaseAmountDkkMth 247 248 </span> 249 </div> 250 251 } 252 <div class="flex-fill"> 253 <div class="d-flex gap-2 justify-content-end"> 254 @if (!hidePrice) 255 { 256 <div class="text-end d-block d-lg-none"> 257 @RenderPrice(product) 258 </div> 259 } 260 @if (!anonymousUser && !hideFavoritesSelector && product.VariantInfo.VariantInfo == null) 261 { 262 <div> 263 @RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters) 264 </div> 265 } 266 @RenderAddToCart(product) 267 </div> 268 @if (!Model.Item.GetBoolean("HideStockState")) 269 { 270 <div class="text-end align-self-end mt-1 d-none d-lg-block"> 271 @if (!Model.Item.GetBoolean("HideStockState")) 272 { 273 @RenderStockState(product) 274 } 275 </div> 276 } 277 </div> 278 279 </div> 280 </article> 281 282 } 283 284 <div class="my-3"> 285 <div class="text-center d-flex flex-column gap-3"> 286 <div class="opacity-85">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div> 287 @if (productList.PageCount != 1) 288 { 289 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? "NameForSort"; 290 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection; 291 292 <form method="get" action="@url" data-response-target-element="content" class="w-100"> 293 @foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 294 { 295 foreach (FacetViewModel facetItem in facetGroup.Facets) 296 { 297 foreach (FacetOptionViewModel facetOption in facetItem.Options) 298 { 299 if (facetOption.Selected) 300 { 301 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]" /> 302 } 303 } 304 } 305 } 306 307 @if (productList?.Group?.Id != null) 308 { 309 <input type="hidden" name="GroupId" value="@productList.Group.Id" /> 310 } 311 312 <input type="hidden" name="PageSize" value="@pageSize" /> 313 <input type="hidden" name="SortBy" value="@sortBySelection" /> 314 <input type="hidden" name="RequestType" value="UpdateList" /> 315 316 <button class="btn btn-primary" type="button" onclick="swift.ProductList.Update(event)">@Translate("Load more products")</button> 317 </form> 318 } 319 </div> 320 </div> 321 322 if (!hideAddToCart) 323 { 324 <div class="modal fade js-product" id="VariantSelectorModal_@Model.ID" tabindex="-1" aria-hidden="true"> 325 <div class="modal-dialog modal-dialog-centered modal-md"> 326 <div class="modal-content @modalTheme" id="VariantSelectorModalContent_@Model.ID"> 327 @* The content here comes from an external request *@ 328 </div> 329 </div> 330 </div> 331 } 332 } 333 else 334 { 335 if (!Pageview.IsVisualEditorMode) 336 { 337 <div class="alert alert-dark m-0"> 338 @Translate("We did not find anything matching your search result") 339 </div> 340 } 341 else 342 { 343 <div class="alert alert-dark m-0" role="alert"> 344 <span>@Translate("Product list: The list will be shown here, if any")</span> 345 </div> 346 } 347 } 348 } 349 350 @helper RenderMainFeatures(List<CategoryFieldViewModel> mainFeatures) 351 { 352 if (mainFeatures.Count > 0) 353 { 354 string featuresLayout = Model.Item.GetRawValueString("FeaturesLayout", "bullets"); 355 356 if (featuresLayout == "bullets") 357 { 358 <ul class="m-0 p-0 lh-1 fs-7 opacity-75" style="list-style-position: inside"> 359 @foreach (CategoryFieldViewModel mainFeatureGroup in mainFeatures) 360 { 361 foreach (var field in mainFeatureGroup.Fields) 362 { 363 @RenderField(field.Value) 364 } 365 } 366 </ul> 367 } 368 else 369 { 370 List<string> featuresList = new List<string>(); 371 foreach (CategoryFieldViewModel mainFeatureGroup in mainFeatures) 372 { 373 foreach (var field in mainFeatureGroup.Fields) 374 { 375 if (field.Value.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 376 { 377 List<string> options = new List<string>(); 378 foreach (FieldOptionValueViewModel option in field.Value.Value as System.Collections.Generic.List<FieldOptionValueViewModel>) 379 { 380 if (!string.IsNullOrWhiteSpace(option.Value)) 381 { 382 if (option.Value.ToString().Contains("#") && (Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 383 { 384 string colorSpan = "<span class=\"colorbox-sm\" style=\"background-color: " + option.Value + "\"></span>"; 385 options.Add(colorSpan); 386 } 387 else 388 { 389 options.Add(option.Value); 390 } 391 } 392 } 393 string optionsString = (string.Join(", ", options.Select(x => x.ToString()).ToArray())); 394 if ((Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 395 { 396 optionsString = (string.Join(" ", options.Select(x => x.ToString()).ToArray())); 397 } 398 featuresList.Add(field.Value.Name + ": " + optionsString); 399 } 400 else 401 { 402 if (!string.IsNullOrWhiteSpace(field.Value.Value.ToString())) 403 { 404 if (field.Value.Value.ToString().Contains("#") && (Translate(field.Value.Name) == Translate("Color") || Translate(field.Value.Name) == Translate("Colour"))) 405 { 406 string colorSpan = "<span class=\"colorbox-sm\" style=\"background-color: " + field.Value.Value + "\"></span>"; 407 featuresList.Add(field.Value.Name + ": " + colorSpan); 408 } 409 else 410 { 411 featuresList.Add(field.Value.Name + ": " + field.Value.Value.ToString()); 412 } 413 } 414 } 415 } 416 } 417 string featuresString = (string.Join(", ", featuresList.Select(x => x.ToString()).ToArray())); 418 419 <div class="opacity-75 fs-7">@featuresString</div> 420 } 421 } 422 } 423 424 @helper RenderField(FieldValueViewModel field) 425 { 426 string fieldValue = field?.Value != null ? field.Value.ToString() : ""; 427 428 if (fieldValue != "") 429 { 430 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 431 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 432 433 if (field.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) 434 { 435 fieldValue = ""; 436 List<string> options = new List<string>(); 437 foreach (FieldOptionValueViewModel option in field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>) 438 { 439 if (!string.IsNullOrWhiteSpace(option.Value)) 440 { 441 if (option.Value.ToString().Contains("#") && (Translate(field.Name) == Translate("Color") || Translate(field.Name) == Translate("Colour"))) 442 { 443 string colorSpan = "<span class=\"colorbox-sm\" style=\"background-color: " + option.Value + "\"></span>"; 444 options.Add(colorSpan); 445 } 446 else 447 { 448 options.Add(option.Name); 449 } 450 } 451 } 452 string optionsString = (string.Join(", ", options.Select(x => x.ToString()).ToArray())); 453 if ((Translate(field.Name) == Translate("Color") || Translate(field.Name) == Translate("Colour"))) 454 { 455 optionsString = (string.Join(" ", options.Select(x => x.ToString()).ToArray())); 456 } 457 458 fieldValue = optionsString; 459 } 460 461 if (!string.IsNullOrEmpty(fieldValue)) 462 { 463 <li>@(field.Name): @fieldValue</li> 464 } 465 } 466 } 467 468 @helper RenderStockState(ProductViewModel product) 469 { 470 bool isNeverOutOfStock = product.NeverOutOfstock; 471 bool hasExpectedDelivery = product.ExpectedDelivery != null && product.ExpectedDelivery > DateTime.Now; 472 string expectedDeliveryDate = product.ExpectedDelivery?.ToShortDateString() ?? ""; 473 474 string stockLevel = product.StockLevel > 100 ? "100+" : product.StockLevel.ToString(); 475 476 if (!isNeverOutOfStock) 477 { 478 if (product.StockLevel > 0) 479 { 480 if (!Model.Item.GetBoolean("HideInventory")) 481 { 482 <p class="fs-7 text-success m-0">@stockLevel @Translate("In stock")</p> 483 } 484 else 485 { 486 <p class="fs-7 text-success m-0">@Translate("In stock")</p> 487 } 488 } 489 else 490 { 491 <p class="fs-7 text-danger m-0">@Translate("Out of Stock")</p> 492 } 493 494 if (hasExpectedDelivery) 495 { 496 <p> 497 <span>@Translate("Expected:")</span> 498 <span>@expectedDeliveryDate</span> 499 </p> 500 } 501 } 502 } 503 504 @helper RenderAddToCart(ProductViewModel product) 505 { 506 string iconPath = "/Files/icons/"; 507 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 508 if (!url.Contains("LayoutTemplate")) 509 { 510 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 511 } 512 513 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 514 bool anonymousUser = Pageview.User == null; 515 516 bool hideAddToCart = !string.IsNullOrEmpty(Model.Item.GetString("HideAddToCart")) ? Model.Item.GetBoolean("HideAddToCart") : false; 517 hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser ? true : hideAddToCart; 518 bool quantitySelector = !string.IsNullOrEmpty(Model.Item.GetString("QuantitySelector")) ? Model.Item.GetBoolean("QuantitySelector") : false; 519 520 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 521 bool isNeverOutOfStock = product.NeverOutOfstock; 522 disableAddToCart = isNeverOutOfStock ? "" : disableAddToCart; 523 524 if (!hideAddToCart) 525 { 526 if (product.VariantInfo.VariantInfo == null) 527 { 528 string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; 529 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 530 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 531 string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : ""; 532 533 <form method="post" action="@url" class="d-inline-block"> 534 <input type="hidden" name="redirect" value="false" /> 535 <input type="hidden" name="ProductId" value="@product.Id" /> 536 <input type="hidden" name="cartcmd" value="add" /> 537 538 @if (!string.IsNullOrEmpty(product.VariantId)) 539 { 540 <input type="hidden" name="VariantId" value="@product.VariantId" /> 541 } 542 543 @if (quantitySelector) 544 { 545 <div class="input-group input-primary-button-group d-flex flex-row w-100"> 546 <label for="Quantity_@(product.Id)_@product.VariantId" class="visually-hidden">@Translate("Quantity")</label> 547 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" step="@stepQty" @minQty class="form-control" style="max-width: 100px" type="number"> 548 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)"><span class="icon-2">@ReadFile(iconPath + "shopping-cart.svg")</span></button> 549 @if (stepQty != "1") 550 { 551 <div class="invalid-feedback d-none"> 552 @Translate("Please select a quantity that is dividable by") @stepQty 553 </div> 554 } 555 </div> 556 } 557 else 558 { 559 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" type="hidden"> 560 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary js-add-to-cart-button" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)"><span class="icon-2">@ReadFile(iconPath + "shopping-cart.svg")</span></button> 561 } 562 </form> 563 } 564 else 565 { 566 string buttonWidth = quantitySelector ? "width: calc(80px + 3.5rem);" : "max-width: 3.5rem;"; 567 string buttonText = quantitySelector ? Translate("Select") : "<span class=\"icon-2\">" + @ReadFile(iconPath + "shopping-cart.svg") + "</span>"; 568 569 string variantSelectorServicePageId = !string.IsNullOrEmpty(Model.Item.GetString("VariantSelectorServicePageId")) ? Model.Item.GetLink("VariantSelectorServicePageId").PageId.ToString() : ""; 570 variantSelectorServicePageId = variantSelectorServicePageId != "" ? variantSelectorServicePageId : GetPageIdByNavigationTag("RelatedProductsListService").ToString(); 571 572 <form action="/Default.aspx?ID=@variantSelectorServicePageId" data-response-target-element="VariantSelectorModalContent_@Model.ID" data-preloader="inline" class="d-inline-block"> 573 <input type="hidden" name="ProductID" value="@product.Id" /> 574 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()" /> 575 <input type="hidden" name="ViewType" value="ModalContent" /> 576 <button type="button" onclick="swift.PageUpdater.Update(event)" class="btn btn-primary" title="@Translate("Select")" style="@buttonWidth" data-bs-toggle="modal" data-bs-target="#VariantSelectorModal_@Model.ID">@buttonText</button> 577 </form> 578 } 579 } 580 } 581 582 @helper RenderPrice(ProductViewModel product) 583 { 584 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 585 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 586 string priceMin = ""; 587 string priceMax = ""; 588 589 590 591 string customerNumber = null; 592 if (Pageview.User != null) 593 { 594 customerNumber = Pageview.User.CustomerNumber; 595 596 } 597 <div class="text-end lh-1 my-auto my-lg-0 g-col-12"> 598 <div> 599 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 600 601 @if (showPricesWithVat == "false" && !neverShowVat) 602 { 603 string beforePrice = product.PriceBeforeDiscount.PriceWithoutVatFormatted; 604 605 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span> 606 if (product.Price.Price != product.PriceBeforeDiscount.Price) 607 { 608 <span class="text-decoration-line-through opacity-75 me-2 text-price">@beforePrice</span> 609 } 610 } 611 else 612 { 613 string beforePrice = product.PriceBeforeDiscount.PriceFormatted; 614 615 <span itemprop="price" content="@product.Price.Price" class="d-none"></span> 616 if (product.Price.Price != product.PriceBeforeDiscount.Price) 617 { 618 <span class="text-decoration-line-through opacity-75 me-2 text-price">@beforePrice</span> 619 } 620 } 621 622 @if (showPricesWithVat == "false" && !neverShowVat) 623 { 624 string price = product.Price.PriceWithoutVatFormatted; 625 if (product?.VariantInfo?.VariantInfo != null) 626 { 627 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 628 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 629 } 630 if (priceMin != priceMax) 631 { 632 price = priceMin + " - " + priceMax; 633 } 634 <span class="text-price">@price</span> 635 } 636 else 637 { 638 string price = product.Price.PriceFormatted; 639 if (product?.VariantInfo?.VariantInfo != null) 640 { 641 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 642 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 643 } 644 if (priceMin != priceMax) 645 { 646 price = priceMin + " - " + priceMax; 647 } 648 <div class="w-100 d-flex justify-content-between fw-bold"> 649 <span class="float-start text-wrap pe-2">@Translate("TCO price"):</span> 650 <span class="text-price float-end">@price</span> 651 </div> 652 653 string carSumTaxBaseAmountDkk = Decimal.TryParse(Convert.ToString(product.ProductFields["CarSumTaxBaseAmountDkk"].Value), out decimal result) ? result.ToString("C2") : 0.ToString("C2"); 654 string carSumTaxBaseAmountDkkMth = Decimal.TryParse(Convert.ToString(product.ProductFields["CarSumTaxBaseAmountMthDkk"].Value), out decimal result2) ? result2.ToString("C2") : 0.ToString("C2"); 655 656 <div class="clearfix g-col-12 text-black-50"> 657 <span class="text-wrap">@Translate("Tax base"):</span> 658 <span class="text-price float-sm-end"> 659 @carSumTaxBaseAmountDkk 660 </span> 661 </div> 662 663 <div class="clearfix g-col-12 text-black-50"> 664 <span class="text-wrap"> 665 @Translate("Monthly tax"): 666 </span> 667 <span class="text-price float-sm-end"> 668 @carSumTaxBaseAmountDkkMth 669 670 </span> 671 </div> 672 } 673 </div> 674 675 @if (showPricesWithVat == "false" && !neverShowVat) 676 { 677 string price = product.Price.PriceWithVatFormatted; 678 if (product?.VariantInfo?.VariantInfo != null) 679 { 680 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 681 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 682 } 683 if (priceMin != priceMax) 684 { 685 price = priceMin + " - " + priceMax; 686 } 687 <div class="fs-7 opacity-85 text-price">@price @Translate("Incl. VAT")</div> 688 } 689 </div> 690 } 691
Ved at klikke ”Acceptér Alle” gives samtykke til at anvende cookies samt indsamling af persondata, som bidrager til forbedring af sitets funktionalitet, statistiske udtræk samt marketingrelaterede aktiviteter.