Error executing template "Designs/Swift-v2/eCom7/CartV2/Step/Cart.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_911eb93972564093bb4cf7d25560597b.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) in /_/src/Application/Providers/Dynamicweb.Rendering.Providers.NetCore/Razor/RazorTemplateRenderingProvider.cs:line 68 at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) in E:\dw10agent2\_w\3\s\src\Core\Dynamicweb.Core\Rendering\TemplateRenderingService.cs:line 14 at Dynamicweb.Rendering.Template.RenderRazorTemplate() in E:\dw10agent2\_w\3\s\src\Core\Dynamicweb.Core\Rendering\Template.cs:line 805
1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb @{ bool anonymousUser = Pageview.User == null; string iconPath = "/Files/Images/Icons/"; int currentUserId = Dynamicweb.Core.Converter.ToInt32(GetGlobalValue("Global:Extranet.UserID")); var shopPageId = GetPageIdByNavigationTag("Shop"); var cart = Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(Pageview.CurrentParagraph)?.Item ?? null; var checkoutAnonymousLink = cart?.GetLink("CheckoutAnonymousPageLink") is object ? cart.GetLink("CheckoutAnonymousPageLink").Url : string.Empty; var checkoutSignedInLink = cart?.GetLink("CheckoutSignedInPageLink") is object ? cart.GetLink("CheckoutSignedInPageLink").Url : string.Empty; string checkoutLink = currentUserId == 0 ? checkoutAnonymousLink : checkoutSignedInLink; var quoteCheckoutLink = cart?.GetLink("QuoteCheckoutPageLink") is object ? cart.GetLink("QuoteCheckoutPageLink").Url : string.Empty; bool isQuote = Dynamicweb.Ecommerce.Services.Orders.GetById(GetString("Ecom:Order.ID")).IsQuote; var cartServicePageId = GetPageIdByNavigationTag("CartService"); } <div class="grid gap-0" id="Cart"> <header class="g-col-12"> <div class="pb-3 pb-lg-0 pt-3 pt-lg-5"> <h1 class="h3 mb-2">@Translate("Shopping Cart")</h1> <p class="mb-0"><span>@Translate("Items in your shopping cart"):</span> <span>@GetString("Ecom:Order.OrderLines.TotalProductQuantity")</span></p> </div> </header> <div class="g-col-12 g-col-lg-8 pe-lg-5 pb-md-5"> @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Ecommerce.Orders @if (GetLoop("ValidationErrors").Count() != 0) { <div class="alert alert-warning" role="alert"> <ul class="m-0 list-unstyled"> @foreach (LoopItem item in GetLoop("ValidationErrors")) { <li>@item.GetValue("Ecom:Cart.ValidationError.ErrorMessage")</li> } </ul> </div> } @* Logic to remove the voucher code error, when going to next step in checkout *@ @{ string voucherCodeForErrorCheck = GetString("Ecom:Order.Customer.VoucherCode"); Order? orderForErrorCheck = !string.IsNullOrEmpty(GetString("Ecom:Order.ID")) ? new OrderService().GetById(GetString("Ecom:Order.ID")) : null; voucherCodeForErrorCheck = orderForErrorCheck?.VoucherUseType == VoucherUseCategoryType.None ? string.Empty : voucherCodeForErrorCheck; } <input type="hidden" name="EcomOrderVoucherCode" value="@voucherCodeForErrorCheck"> <form name="ordersubmit" id="ordersubmit" method="post" autocomplete="off"> <input type="hidden" name="cartcmd" value="updateorderlines" /> <input type="hidden" name="redirect" value="false" /> <input type="hidden" name="LayoutTemplate" value="Swift-v2_MiniCart.cshtml" /> <header class="py-2 pt-lg-5 border-bottom d-none d-lg-block"> <div class="grid" style="line-height: 1;"> <div class="g-col-2">@Translate("Product")</div> <div class="g-col-9 grid"> <div class="g-col-10 g-col-md-6 g-start-8"></div> <div class="g-col-2 g-col-md-3 g-start-8">@Translate("Quantity")</div> </div> <div class="g-col-1 text-end">@Translate("Total")</div> </div> </header> <script> gtag("event", "view_cart", { currency: "@GetString("Ecom:Order.Currency.Code")", value: @GetDouble("Ecom:Order.Price.PriceWithVAT.Value").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), items: [ @foreach (LoopItem orderline in GetLoop("OrderLines")) { <text> { item_id: "@orderline.GetString("Ecom:Order:OrderLine.ProductID")", item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(orderline.GetString("Ecom:Order:OrderLine.ProductName"))", currency: "@orderline.GetString("Ecom:Order:OrderLine.UnitPrice.CurrencyCode")", price: @orderline.GetDouble("Ecom:Order:OrderLine.UnitPriceWithProductDiscount.Price.Value").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), discount: @Math.Abs(orderline.GetDouble("Ecom:Order:OrderLine.UnitDiscount.Price.Value")).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), quantity: @orderline.GetDouble("Ecom:Order:OrderLine.Quantity").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture) },</text> } ] }); </script> @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Frontend @using Dynamicweb.Rendering @using System.Globalization @using System @functions{ string? DoubleToString(double? value) { if (value.HasValue) { return Math.Round(value.Value, 2).ToString(CultureInfo.InvariantCulture); } return null; } } @{ var orderlines = GetLoop("OrderLines"); } @for (int i = orderlines.Count - 1; i >= 0; i--) { var orderline = orderlines[i]; bool neverOutOfStock = orderline.GetBoolean("Ecom:Product.NeverOutOfStock"); string name = orderline.GetString("Ecom:Order:OrderLine.ProductName"); string primaryImage = orderline.GetString("Ecom:Product.PrimaryImage"); string image = $"/Admin/Public/GetImage.ashx?width=180&height=180&image={primaryImage}&format=webp"; string removeFromBasketLink = orderline.GetString("Ecom:Order:OrderLine.DeleteLink"); string priceTotalWithDiscounts = orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.PriceFormatted"); string priceTotalWithDiscountsClean = orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.Price"); string unitPrice = orderline.GetString("Ecom:Order:OrderLine.UnitPrice.PriceFormatted"); string unitPriceWithDiscount = orderline.GetDouble("Ecom:Order:OrderLine.UnitPriceWithProductDiscount.Price.Value").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture); string discountAmount = Math.Abs(orderline.GetDouble("Ecom:Order:OrderLine.UnitDiscount.Price.Value")).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture); string unitPriceCurrency = orderline.GetString("Ecom:Order:OrderLine.Price.CurrencyCode"); string discountPrice = orderline.GetString("Ecom:Order:OrderLine.UnitPriceWithProductDiscount.PriceFormatted"); string discountTotal = orderline.GetString("Ecom:Order:OrderLine.TotalDiscount.PriceFormatted"); string variantText = orderline.GetString("Ecom:Order:OrderLine.ProductVariantText"); var orderlineId = orderline.GetValue("Ecom:Order:OrderLine.Id"); double? stepQty = orderline.GetDouble("Ecom:Product.PurchaseQuantityStep") > 0 ? orderline.GetDouble("Ecom:Product.PurchaseQuantityStep") : 1; var quantity = orderline.GetDouble("Ecom:Order:OrderLine.Quantity"); var unitName = orderline.GetString("Ecom:Order:OrderLine.UnitName"); string primaryGroupId = orderline.GetString("Ecom:Order:OrderLine.PrimaryOrDefaultGroupId"); string productId = orderline.GetString("Ecom:Order:OrderLine.ProductID"); string variantId = orderline.GetString("Ecom:Order:OrderLine.ProductVariantID"); string unitId = orderline.GetString("Ecom:Order:OrderLine.UnitID"); string productType = orderline.GetString("Ecom.Product.Type"); double? stockQuantity = orderline.GetDouble("Ecom:Product.Stock"); double? minQty = orderline.GetDouble("Ecom:Product.PurchaseMinimumQuantity") > 0 ? orderline.GetDouble("Ecom:Product.PurchaseMinimumQuantity") : 1; bool isStockType = orderline.GetInteger("Ecom.Product.Type") == 0; bool setMaxQty = isStockType && !neverOutOfStock; double? maxQty = setMaxQty ? stockQuantity : null; string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 2 link += $"&GroupID={System.Net.WebUtility.UrlEncode(primaryGroupId)}"; 3 link += $"&ProductID={System.Net.WebUtility.UrlEncode(productId)}"; 4 link += !string.IsNullOrEmpty(variantId) ? $"&VariantID={System.Net.WebUtility.UrlEncode(variantId)}" : ""; 5 6 bool isProductIdOrNumber = !string.IsNullOrEmpty(orderline.GetString("Ecom:Order:OrderLine.ProductID")) || !string.IsNullOrEmpty(orderline.GetString("Ecom:Order:OrderLine.ProductNumber")); //Live Cart orderlines may not return ProductId. Manually entered products may not have ProductNumber bool isProduct = orderline.GetBoolean("Ecom:Order:OrderLine.IsProduct") || (orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount") && isProductIdOrNumber); bool orderIsQuote = Dynamicweb.Ecommerce.Services.Orders.GetById(GetString("Ecom:Order.ID")).IsQuote; if (isProduct) { var bomItems = orderline.GetLoop("BOMItems"); <article class="grid pt-3" style="row-gap: 0;" data-product-id="@productId" data-variant-id="@variantId" data-unit-id="@unitId" data-orderline-total-price="@priceTotalWithDiscountsClean" data-orderline-unit-price="@unitPriceWithDiscount"> <div class="g-col-3 g-col-lg-2"> <a href="@link" class="ratio ratio-1x1 d-block" title="@name"> <img class="cart-item-img" src="@image" style="object-fit: contain;" alt="@name"> </a> </div> <div class="g-col-9 g-col-lg-10"> <div class="grid" style="row-gap: 0.5rem;--bs-gap:0;"> <div class="g-col-12 g-col-md-8 grid grid-7 grid-md-9" style="row-gap: 0.5rem;"> <div class="g-col-7 g-col-md-6"> @* Title *@ <h3 class="fs-7 fs-md-6 mb-0"> <a href="@link" class="text-decoration-none" title="@name">@name</a> </h3> @* Variants *@ @if (!string.IsNullOrEmpty(variantText)) { <p class="mt-2 mb-0 fs-7 fs-md-6">@variantText</p> } @if (orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount")) { @* Free product notice *@ <p class="mt-2 mb-0 fs-7 fs-md-6 opacity-75">@Translate("Free product")</p> } else { @* Unit price *@ <p class="fs-7 fs-md-6 mt-2 mb-0"> @if (!string.IsNullOrEmpty(unitName)) { <span>@unitName: </span> } @if (discountPrice == unitPrice) { <span class="text-price">@unitPrice</span> } else { <span class="text-price">@discountPrice</span> <span class="text-decoration-line-through fs-7"> <span class="text-price">@unitPrice</span> </span> } </p> } </div> <div class="g-col-7 g-col-md-3"> @if (!orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount") && !orderIsQuote) { @* Quantity *@ <div class="input-group js-input-group"> @{ var orderlineViewModel = new Dynamicweb.Ecommerce.Frontend.OrderLineViewModel(){ Id = orderlineId.ToString(), ProductId = productId, ProductVariantId = variantId, UnitId = unitId, Quantity = quantity }; } @RenderPartial("Components/QuantitySelectorOrderline.cshtml", orderlineViewModel) </div> } else { <div class="text-center" style="max-width: 140px;">@quantity</div> } </div> </div> <div class="g-col-12 g-col-md-4 text-end"> @* Total *@ <div class="fs-7 fs-md-6"> <span class="text-price">@priceTotalWithDiscounts</span> </div> @if (orderline.GetDouble("Ecom:Order:OrderLine.TotalDiscount.Price.Value") != 0) { <div class="fs-8"> <span class="text-price">@discountTotal</span> </div> } </div> <div class="g-col-12"> @if (!orderIsQuote) { string clickProductLink = "onclick=\"return removeProductLink('" + @productId + "', '" + @Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(name) + "', '" + @Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(variantText) + "', '" + @unitPriceCurrency + "', '" + @unitPriceWithDiscount + "', '" + @discountAmount + "', '" + @quantity.ToString().Replace(",", ".") + "')\""; <a href="@removeFromBasketLink" class="btn btn-link btn-sm p-0 m-0 fs-8" title="@Translate("Remove")" @clickProductLink>@Translate("Remove")</a> } <script> function removeProductLink(productId, productName, productVariant, productCurrency, productPrice, productDiscount, productQuantity) { if (typeof gtag !== "undefined") { gtag("event", "remove_from_cart", { currency: productCurrency, value: (parseFloat(productPrice) * parseFloat(productQuantity)), items: [ { item_id: productId, item_name: productName, item_variant: productVariant, currency: productCurrency, price: productPrice, discount: productDiscount, item_list_id: "cart", item_list_name: "Cart", quantity: productQuantity } ] }); } } </script> </div> </div> </div> @* Bottom border *@ <div class="g-col-12 mt-3"> <span class="d-none d-lg-block border-bottom"></span> </div> @if (bomItems.Count > 0) { <div class="g-col-12 mt-3"> @* BOM items *@ @foreach (var bomItem in bomItems) { string bomImage = bomItem.GetString("Ecom:Product.PrimaryImage"); bomImage = !bomImage.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? bomImage : $"/Admin/Public/GetImage.ashx?width=200&height=200&image={bomImage}&format=webp"; string bomPriceTotalWithDiscounts = bomItem.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.PriceFormatted"); string bomDiscountTotal = bomItem.GetString("Ecom:Order:OrderLine.TotalDiscount.PriceFormatted"); var bomVariantName = string.Join(" ", bomItem.GetLoop("VariantGroups") .SelectMany(g => g.GetLoop("VariantOptions")) .Where(o => o.GetBoolean("Ecom:VariantOption.Selected")) .Select(o => $"<span>{o.GetString("Ecom:VariantOption.Name")} </span>")); <div class="grid"> <div class="g-col-3 g-col-lg-2 d-flex align-items-center gap-2"> <div class="icon-2 p-0 p-lg-3 opacity-25"> @ReadFile("/Files/Images/Icons/arrow-turn-down-right.svg") </div> @if (!string.IsNullOrEmpty(bomImage)) { <div class="ratio ratio-1x1 d-block" title="@name"> <img class="cart-item-img" src="@bomImage" style="object-fit: contain;" alt="@name"> </div> } </div> <div class="g-col-9 g-col-lg-10 grid" style="row-gap: 0.5rem; --bs-gap:0;"> <div class="g-col-12 g-col-md-8 grid grid-7 grid-md-9"> <div class="g-col-7 g-col-md-6"> <h3 class="fs-7 fs-md-6 m-0">@bomItem.GetString("Ecom:Product.Name") </h3> <div class="fs-7 fs-md-6">@bomVariantName</div> </div> <div class="g-col-7 g-col-md-3"> <p class="fs-7 fs-md-6 mb-0 text-center" style="max-width: 140px;">@bomItem.GetDouble("Ecom:Order:OrderLine.Quantity")</p> </div> </div> <div class="g-col-12 g-col-md-4 text-end"> @* Total - Hide when PriceType = Fixed *@ @if (orderline.GetInteger("Ecom:Product.PriceType") != 1) { <div class="fs-7 fs-md-6"> <span class="text-price">@bomPriceTotalWithDiscounts</span> </div> if (bomItem.GetDouble("Ecom:Order:OrderLine.TotalDiscount.Price.Value") != 0) { <div class="fs-8"> <span class="text-price">@bomDiscountTotal</span> </div> } } </div> </div> </div> @* Bottom border *@ <div class="w-100 my-3"> <span class="d-none d-lg-block border-bottom"></span> </div> } </div> } </article> } } @if(Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop) { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Ecommerce.Orders @* Red lines may be due to variables defined in the parent tempalte - There is no actual error *@ @{ <div class="align-items-center d-grid d-lg-flex gap-2 justify-content-lg-end mt-lg-4"> <a href="Default.aspx?ID=@shopPageId" class="btn btn-link text-decoration-none me-lg-3 order-last order-lg-first swift_cartbackbutton" data-dw-button="link"> <span class="d-flex align-items-center justify-content-center position-relative"> <span class="icon-2 me-1 position-absolute position-lg-static start-0"> @ReadFile(iconPath + "chevron-left.svg") </span> <span>@Translate("Continue shopping")</span> </span> </a> @if (!anonymousUser && isQuote) { <a href="@($"{Context.Current.Request.Url}&cartcmd=emptycart")" class="btn btn-secondary" data-dw-button="secondary"> <span class="d-flex align-items-center justify-content-center position-relative"> <span>@Translate("Clear Cart")</span> <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> @ReadFile(iconPath + "trash-can.svg") </span> </span> </a> } @if (!string.IsNullOrEmpty(quoteCheckoutLink) && !anonymousUser && !isQuote) { <a href="@quoteCheckoutLink" class="btn btn-secondary" data-dw-button="secondary"> <span class="d-flex align-items-center justify-content-center position-relative"> <span>@Translate("Request quote")</span> <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> @ReadFile(iconPath + "chevron-right.svg") </span> </span> </a> } <a href="@checkoutLink" class="btn btn-primary" data-dw-button="primary" id="GoToCheckoutButton"> <span class="d-flex align-items-center justify-content-center position-relative"> <span>@Translate("Checkout")</span> <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> @ReadFile(iconPath + "chevron-right.svg") </span> </span> </a> </div> } </text> } </form> </div> <aside class="g-col-12 g-col-lg-4 position-relative"> <div class="p-3 p-lg-5 pb-lg-4 sticky-top z-1" data-dw-colorscheme="@Pageview.CurrentParagraph?.ColorSchemeId"> <header> <h4 class="fs-6 fw-normal mb-2">@Translate("Order summary")</h4> </header> @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @{ double totalPriceWithoutOrderDiscountsFeesAndTaxesValue = GetDouble("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.Price.Value") + GetDouble("Ecom:Order.TotalProductDiscount.Price.Value"); var orderCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(GetString("Ecom:Order.Currency.Code")); string totalPriceWithoutOrderDiscountsFeesAndTaxes = orderCurrency != null ? Dynamicweb.Ecommerce.Services.Currencies.Format(orderCurrency, totalPriceWithoutOrderDiscountsFeesAndTaxesValue) : string.Empty; bool showPricesWithVat = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; bool renderVatMessage = (GetString("Ecom:Order.OrderLines.Total.PriceWithVAT") != GetString("Ecom:Order.OrderLines.Total.PriceWithoutVAT")) || Dynamicweb.Ecommerce.Common.Context.Country?.Vat != null; bool disableVouchers = Pageview.CurrentParagraph?.Item["DisableVouchers"] != null ? (Boolean)Pageview.CurrentParagraph.Item["DisableVouchers"] : false; disableVouchers = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("CompletedOrderId")) ? true : disableVouchers; <div class="d-flex flex-column gap-2 gap-lg-3 pb-3 bottom-0 sticky-receipt" id="orderSummaryFooter"> @if (!disableVouchers && Pageview.CurrentParagraph?.Item.SystemName != "Swift-v2_QuoteCheckoutApp") { <text> @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Ecommerce.Orders @{ string voucherCode = GetString("Ecom:Order.Customer.VoucherCode"); string voucherCodeError = GetString("Ecom:Cart.ValidationError.EcomOrderVoucherCode.ErrorMessage"); string validState = string.Empty; bool vouchersAppliedAsDiscounts = false; IEnumerable<string> voucherCodes = new List<string>(); Order order = new OrderService().GetById(GetString("Ecom:Order.ID")); if (!string.IsNullOrWhiteSpace(voucherCode)) { if (order.VoucherUseType.HasFlag(VoucherUseCategoryType.Discount)) { voucherCodes = voucherCode.Split(new string[] { ",", ";", " " }, StringSplitOptions.RemoveEmptyEntries); vouchersAppliedAsDiscounts = true; } else { voucherCodes = new string[] { voucherCode.Trim() }; } } var voucherErrors = new List<string>(); if(!vouchersAppliedAsDiscounts) { foreach (string code in voucherCodes) { Dynamicweb.Ecommerce.Orders.Vouchers.Voucher vouch = Dynamicweb.Ecommerce.Services.Vouchers.GetVoucherByCode(code); if (vouch == null) { validState = "is-invalid"; voucherErrors.Add(Translate("Voucher") + " <span class='fw-bold'>" + code + "</span> " + Translate("not found")); continue; } if (vouch.DateUsed.HasValue) { validState = "is-invalid"; voucherErrors.Add(Translate("Voucher") + " <span class='fw-bold'>" + code + "</span> " + Translate("already used")); continue; } } } var voucherErrorMessage = string.Join(",", voucherErrors); <div class="py-3 border-top" id="orderVoucherForm"> <form method="post" id="VoucherForm"> <div class="input-group input-primary-button-group has-validation"> <input type="text" class="form-control @(validState)" name="EcomOrderVoucherCodeField" placeholder="@Translate("Add voucher here")" id="EcomOrderVoucherCodeField" value="" aria-label="@Translate("Voucher input")" oninput="document.querySelector('#EcomOrderVoucherCode').value = this.value;" onkeyup="document.querySelector('#EcomOrderVoucherCode').value = this.value;"> <button class="btn btn-sm btn-primary d-inline-flex align-items-center justify-content-center" data-dw-button="primary" type="submit" id="EcomOrderVoucherApply" style="min-width: 100px;"> <span>@Translate("Apply")</span> </button> <div class="invalid-feedback"> @voucherErrorMessage </div> </div> <input type="hidden" name="EcomOrderVoucherCode" id="EcomOrderVoucherCode" value="@voucherCode"> <label for="EcomOrderVoucherCodeField" class="visually-hidden">@Translate("Add voucher here")</label> </form> @if (!string.IsNullOrWhiteSpace(voucherCode)) { <div class="d-flex flex-wrap gap-2 pt-3"> @foreach (string code in voucherCodes) { <form method="post"> <input type="hidden" name="EcomOrderVoucherCode" value="@voucherCode.Replace(code+",", "").Replace(","+code, "").Replace(code, "")"> <span class="badge fw-normal d-inline-flex align-items-center justify-content-center opacity-50 opacity-100-hover" style="background-color:var(--dw-color-foreground);color:var(--dw-color-background);"> <button type="submit" class="text-reset bg-transparent border-0 p-0" aria-label="@Translate("Remove voucher")" id="RemoveVoucherButton"> <span class="icon-2"> @ReadFile("/Files/Images/Icons/xmark.svg") </span> <span class="mx-2">@code</span> </span> </form> } </div> } @voucherCodeError </div> } </text> } <div class="fs-8 border-top pt-2 pt-lg-3"> @* Subtotal *@ <div class="d-flex justify-content-between fw-bold"> <span>@Translate("Subtotal")</span> <span class="text-end"> <span class="d-block"> @if (GetDouble("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.Price.Value") != totalPriceWithoutOrderDiscountsFeesAndTaxesValue) { <span class="text-price fw-normal text-decoration-line-through">@GetString("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.PriceFormatted")</span> } <span class="text-price">@totalPriceWithoutOrderDiscountsFeesAndTaxes</span> </span> @if (renderVatMessage && !showPricesWithVat) { <span class="fs-8 fw-normal d-block">@Translate("Excl. VAT")</span> } else if (renderVatMessage) { <span class="fs-8 fw-normal d-block">@Translate("Incl. VAT")</span> } </span> </div> @* Discounts (only order discounts) *@ @foreach (LoopItem orderline in GetLoop("OrderLines")) { bool isDiscount = orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount"); bool isProductIdOrNumber = !string.IsNullOrEmpty(orderline.GetString("Ecom:Order:OrderLine.ProductID")) || !string.IsNullOrEmpty(orderline.GetString("Ecom:Order:OrderLine.ProductNumber")); //Live Cart orderlines may not bool isOrderAmountDiscount = orderline.GetInteger("Ecom:Order:OrderLine.Type") == 1 && !isProductIdOrNumber; if (isDiscount && isOrderAmountDiscount) { <div class="d-flex justify-content-between"> <span>@orderline.GetString("Ecom:Order:OrderLine.ProductName")</span><span class="text-price">@orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.PriceFormatted")</span> </div> } } @* Delivery *@ @if (!string.IsNullOrEmpty(GetString("Ecom:Order.ShippingMethodID"))) { if (GetDouble("Ecom:Order.ShippingFee.Price.Value") != 0.0) { <div class="d-flex justify-content-between"> <span>@Translate("Delivery")</span> <span>@GetString("Ecom:Order.ShippingFee.PriceFormatted")</span> </div> } } else { <div class="d-flex justify-content-between"> <span>@Translate("Delivery")</span> <span>@Translate("Calculated in next step")</span> </div> } @* Payment *@ @if (!string.IsNullOrEmpty(GetString("Ecom:Order.PaymentMethodID"))) { if (GetDouble("Ecom:Order.PaymentFee.Price.Value") != 0) { <div class="d-flex justify-content-between"> <span>@Translate("Payment")</span> <span class="text-price">@GetString("Ecom:Order.PaymentFee.PriceFormatted")</span> </div> } } else { <div class="d-flex justify-content-between"> <span>@Translate("Payment")</span> <span>@Translate("Calculated in next step")</span> </div> } @* Taxes *@ @if (GetDouble("Ecom:Order.Taxes.Total.Price.Value") != 0) { <div class="d-flex justify-content-between mb-2"> <span>@Translate("Sales tax")</span> <span>@GetString("Ecom:Order.Taxes.Total.PriceFormatted")</span> </div> } </div> <div class="fs-8 border-top pt-2 pt-lg-3"> <div class="d-flex justify-content-between fs-6 fw-bold"> <span>@Translate("Total")</span> @if (renderVatMessage && !showPricesWithVat) { <span class="text-price text-end"> <span class="fs-5 d-block">@GetString("Ecom:Order.Price.PriceFormatted")</span> <span class="fs-8 fw-normal d-block">@Translate("Excl. VAT")</span> </span> } else if (renderVatMessage) { <span class="text-price text-end"> <span class="fs-5 d-block">@GetString("Ecom:Order.Price.PriceFormatted")</span> <span class="fs-8 fw-normal d-block">@Translate("Incl. VAT")</span> </span> } else { <span class="text-price fs-5">@GetString("Ecom:Order.Price.PriceFormatted")</span> } </div> @if (renderVatMessage) { <div class="d-flex justify-content-between"><span>@Translate("VAT")</span><span class="text-price">@GetString("Ecom:Order.Price.VATFormatted")</span></div> if (!showPricesWithVat) { <div class="d-flex justify-content-between"><span>@Translate("Total incl. VAT")</span><span class="text-price">@GetString("Ecom:Order.OrderLines.Total.PriceWithVAT")</span></div> } } @if (GetDouble("Ecom:Order.TotalDiscount.Price.Value") != 0) { <div class="d-flex justify-content-between"><span>@Translate("Discount")</span><span class="text-price">@GetString("Ecom:Order.TotalDiscount.PriceFormatted")</span></div> } </div> </div> } @if(Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet) { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using Dynamicweb.Ecommerce.Orders @* Red lines may be due to variables defined in the parent tempalte - There is no actual error *@ @{ <div class="align-items-center d-grid d-lg-flex gap-2 justify-content-lg-end mt-lg-4"> <a href="Default.aspx?ID=@shopPageId" class="btn btn-link text-decoration-none me-lg-3 order-last order-lg-first swift_cartbackbutton" data-dw-button="link"> <span class="d-flex align-items-center justify-content-center position-relative"> <span class="icon-2 me-1 position-absolute position-lg-static start-0"> @ReadFile(iconPath + "chevron-left.svg") </span> <span>@Translate("Continue shopping")</span> </span> </a> @if (!anonymousUser && isQuote) { <a href="@($"{Context.Current.Request.Url}&cartcmd=emptycart")" class="btn btn-secondary" data-dw-button="secondary"> <span class="d-flex align-items-center justify-content-center position-relative"> <span>@Translate("Clear Cart")</span> <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> @ReadFile(iconPath + "trash-can.svg") </span> </span> </a> } @if (!string.IsNullOrEmpty(quoteCheckoutLink) && !anonymousUser && !isQuote) { <a href="@quoteCheckoutLink" class="btn btn-secondary" data-dw-button="secondary"> <span class="d-flex align-items-center justify-content-center position-relative"> <span>@Translate("Request quote")</span> <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> @ReadFile(iconPath + "chevron-right.svg") </span> </span> </a> } <a href="@checkoutLink" class="btn btn-primary" data-dw-button="primary" id="GoToCheckoutButton"> <span class="d-flex align-items-center justify-content-center position-relative"> <span>@Translate("Checkout")</span> <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> @ReadFile(iconPath + "chevron-right.svg") </span> </span> </a> </div> } </text> } </div> </aside> <script> document.addEventListener('updated.swift.cart', (event) => { swift.PageUpdater.Update(document.querySelector("#ordersubmit"), true); }); </script> </div>