Error executing template "Designs/Swift/eCom7/CartV2/Step/Cart.cshtml" System.NullReferenceException: Object reference not set to an instance of an object. at CompiledRazorTemplates.Dynamic.RazorEngine_baec12148d6e47abb3bf7582da609069.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.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, String name, 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 RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, String templateSource, 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 110 at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) in E:\A10\_w\2\s\src\Core\Dynamicweb.Core\Rendering\TemplateRenderingService.cs:line 21 at Dynamicweb.Rendering.Template.RenderRazorTemplate() in E:\A10\_w\2\s\src\Core\Dynamicweb.Core\Rendering\Template.cs:line 749
1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using Dynamicweb 3 4 @{ 5 6 var themeRaw = Pageview.CurrentParagraph.Item["Theme"]?.ToString(); 7 string theme = !string.IsNullOrEmpty(themeRaw) ? " theme " + themeRaw.Replace(" ", string.Empty).Trim().ToLower() : string.Empty; 8 9 bool anonymousUser = Pageview.User == null; 10 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 11 int currentUserId = Dynamicweb.Core.Converter.ToInt32(GetGlobalValue("Global:Extranet.UserID")); 12 var shopPageId = GetPageIdByNavigationTag("Shop"); 13 var cart = Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(Pageview.CurrentParagraph)?.Item ?? null; 14 var checkoutAnonymousLink = cart.GetLink("CheckoutAnonymousPageLink") is object ? cart.GetLink("CheckoutAnonymousPageLink").Url : string.Empty; 15 var checkoutSignedInLink = cart.GetLink("CheckoutSignedInPageLink") is object ? cart.GetLink("CheckoutSignedInPageLink").Url : string.Empty; 16 string checkoutLink = currentUserId == 0 ? checkoutAnonymousLink : checkoutSignedInLink; 17 var quoteCheckoutLink = cart.GetLink("QuoteCheckoutPageLink") is object ? cart.GetLink("QuoteCheckoutPageLink").Url : string.Empty; 18 bool isQuote = Dynamicweb.Ecommerce.Services.Orders.GetById(GetString("Ecom:Order.ID")).IsQuote; 19 } 20 21 <div class="grid gap-0" id="Cart"> 22 <header class="g-col-12"> 23 <div class="pb-3 pb-lg-0 pt-3 pt-lg-5"> 24 <h1 class="h3 mb-2">@Translate("Shopping Cart")</h1> 25 <p class="mb-0"><span>@Translate("Items in your shopping cart"):</span> <span>@GetString("Ecom:Order.OrderLines.TotalProductQuantity")</span></p> 26 </div> 27 </header> 28 29 <div class="g-col-12 g-col-lg-8 pe-lg-5 pb-md-5"> 30 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 31 @using Dynamicweb.Ecommerce.Orders 32 33 @if (GetLoop("ValidationErrors").Count() != 0) 34 { 35 <div class="alert alert-warning" role="alert"> 36 <ul class="m-0 list-unstyled"> 37 @foreach (LoopItem item in GetLoop("ValidationErrors")) 38 { 39 <li>@item.GetValue("Ecom:Cart.ValidationError.ErrorMessage")</li> 40 } 41 </ul> 42 </div> 43 } 44 45 46 @* Logic to remove the voucher code error, when going to next step in checkout *@ 47 @{ 48 string voucherCodeForErrorCheck = GetString("Ecom:Order.Customer.VoucherCode"); 49 Order orderForErrorCheck = new OrderService().GetById(GetString("Ecom:Order.ID")); 50 voucherCodeForErrorCheck = orderForErrorCheck.VoucherUseType == VoucherUseCategoryType.None ? string.Empty : voucherCodeForErrorCheck; 51 } 52 53 <input type="hidden" name="EcomOrderVoucherCode" value="@voucherCodeForErrorCheck"> 54 55 56 <form name="ordersubmit" id="ordersubmit" method="post" autocomplete="off"> 57 58 <header class="py-2 pt-lg-5 border-bottom d-none d-lg-block"> 59 <div class="grid" style="line-height: 1;"> 60 <div class="g-col-2">@Translate("Product")</div> 61 <div class="g-col-9 grid"> 62 <div class="g-col-10 g-col-md-6 g-start-8"></div> 63 <div class="g-col-2 g-col-md-3 g-start-8">@Translate("Quantity")</div> 64 </div> 65 <div class="g-col-1 text-end">@Translate("Total")</div> 66 </div> 67 </header> 68 69 <script> 70 gtag("event", "view_cart", { 71 currency: "@GetString("Ecom:Order.Currency.Code")", 72 value: @GetDouble("Ecom:Order.Price.PriceWithVAT.Value").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), 73 items: [ 74 @foreach (LoopItem orderline in GetLoop("OrderLines")) 75 { 76 <text> 77 { 78 item_id: "@orderline.GetString("Ecom:Order:OrderLine.ProductID")", 79 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(orderline.GetString("Ecom:Order:OrderLine.ProductName"))", 80 currency: "@orderline.GetString("Ecom:Order:OrderLine.UnitPrice.CurrencyCode")", 81 price: @orderline.GetDouble("Ecom:Order:OrderLine.UnitPriceWithProductDiscount.Price.Value").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), 82 discount: @Math.Abs(orderline.GetDouble("Ecom:Order:OrderLine.UnitDiscount.Price.Value")).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), 83 quantity: @orderline.GetDouble("Ecom:Order:OrderLine.Quantity").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture) 84 },</text> 85 } 86 ] 87 }); 88 </script> 89 90 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 91 @using System.Globalization 92 @using System 93 94 @functions{ 95 96 string DoubleToString(double? value) 97 { 98 if (value.HasValue) 99 { 100 return Math.Round(value.Value, 2).ToString(CultureInfo.InvariantCulture); 101 } 102 return null; 103 } 104 } 105 106 @{ 107 var orderlines = GetLoop("OrderLines"); 108 } 109 110 @for (int i = orderlines.Count - 1; i >= 0; i--) 111 { 112 var orderline = orderlines[i]; 113 bool neverOutOfStock = orderline.GetBoolean("Ecom:Product.NeverOutOfStock"); 114 string name = orderline.GetString("Ecom:Order:OrderLine.ProductName"); 115 string primaryImage = orderline.GetString("Ecom:Product.PrimaryImage"); 116 primaryImage = primaryImage.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? primaryImage : $"/Files/{primaryImage}"; 117 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(primaryImage); 118 string image = $"/Admin/Public/GetImage.ashx?width=180&height=180&image={imagePathUrlEncoded}&format=webp"; 119 120 string removeFromBasketLink = orderline.GetString("Ecom:Order:OrderLine.DeleteLink"); 121 string priceTotalWithDiscounts = orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.PriceFormatted"); 122 string priceTotalWithDiscountsClean = orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.Price"); 123 string unitPrice = orderline.GetString("Ecom:Order:OrderLine.UnitPrice.PriceFormatted"); 124 string unitPriceWithDiscount = orderline.GetDouble("Ecom:Order:OrderLine.UnitPriceWithProductDiscount.Price.Value").ToString("0.00", System.Globalization.CultureInfo.InvariantCulture); 125 string discountAmount = Math.Abs(orderline.GetDouble("Ecom:Order:OrderLine.UnitDiscount.Price.Value")).ToString("0.00", System.Globalization.CultureInfo.InvariantCulture); 126 string unitPriceCurrency = orderline.GetString("Ecom:Order:OrderLine.Price.CurrencyCode"); 127 string discountPrice = orderline.GetString("Ecom:Order:OrderLine.UnitPriceWithProductDiscount.PriceFormatted"); 128 string discountTotal = orderline.GetString("Ecom:Order:OrderLine.TotalDiscount.PriceFormatted"); 129 string variantText = orderline.GetString("Ecom:Order:OrderLine.ProductVariantText"); 130 var orderlineId = orderline.GetValue("Ecom:Order:OrderLine.Id"); 131 double? stepQty = orderline.GetDouble("Ecom:Product.PurchaseQuantityStep") > 0 ? orderline.GetDouble("Ecom:Product.PurchaseQuantityStep") : 1; 132 var quantity = orderline.GetDouble("Ecom:Order:OrderLine.Quantity"); 133 var unitName = orderline.GetString("Ecom:Order:OrderLine.UnitName"); 134 string primaryGroupId = orderline.GetString("Ecom:Order:OrderLine.PrimaryOrDefaultGroupId"); 135 string productId = orderline.GetString("Ecom:Order:OrderLine.ProductID"); 136 string variantId = orderline.GetString("Ecom:Order:OrderLine.ProductVariantID"); 137 string unitId = orderline.GetString("Ecom:Order:OrderLine.UnitID"); 138 string productType = orderline.GetString("Ecom.Product.Type"); 139 double? stockQuantity = orderline.GetDouble("Ecom:Product.Stock"); 140 double? minQty = orderline.GetDouble("Ecom:Product.PurchaseMinimumQuantity") > 0 ? orderline.GetDouble("Ecom:Product.PurchaseMinimumQuantity") : 1; 141 bool isStockType = orderline.GetInteger("Ecom.Product.Type") == 0; 142 bool setMaxQty = isStockType && !neverOutOfStock; 143 double? maxQty = setMaxQty ? stockQuantity : null; 144 145 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 146 link += $"&GroupID={primaryGroupId}"; 147 link += $"&ProductID={productId}"; 148 link += !string.IsNullOrEmpty(variantId) ? $"&VariantID={variantId}" : ""; 149 150 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 151 bool isProduct = orderline.GetBoolean("Ecom:Order:OrderLine.IsProduct") || (orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount") && isProductIdOrNumber); 152 bool orderIsQuote = Dynamicweb.Ecommerce.Services.Orders.GetById(GetString("Ecom:Order.ID")).IsQuote; 153 154 if (isProduct) 155 { 156 <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"> 157 <div class="g-col-3 g-col-lg-2"> 158 <a href="@link" class="ratio ratio-1x1 d-block" title="@name"> 159 <img class="cart-item-img" src="@image" style="object-fit: contain;" alt="@name"> 160 </a> 161 </div> 162 163 <div class="g-col-9 g-col-lg-10"> 164 165 <div class="grid" style="row-gap: 0.5rem;"> 166 167 <div class="g-col-12 g-col-md-8 grid grid-7 grid-md-9" style="row-gap: 0.5rem;"> 168 <div class="g-col-7 g-col-md-6"> 169 @* Title *@ 170 <h3 class="h6 fs-7 fs-md-6 mb-0"> 171 <a href="@link" class="text-decoration-none" title="@name">@name</a> 172 </h3> 173 174 @* Variants *@ 175 @if (!string.IsNullOrEmpty(variantText)) 176 { 177 <p class="mt-2 mb-0 fs-7 fs-md-6">@variantText</p> 178 } 179 180 181 @if (orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount")) 182 { 183 @* Free product notice *@ 184 <p class="mt-2 mb-0 fs-7 fs-md-6 opacity-75">@Translate("Free product")</p> 185 } 186 else 187 { 188 @* Unit price *@ 189 <p class="fs-7 fs-md-6 mt-2 mb-0"> 190 @if (!string.IsNullOrEmpty(unitName)) 191 { 192 <span>@unitName: </span> 193 } 194 @if (discountPrice == unitPrice) 195 { 196 <span class="text-price">@unitPrice</span> 197 } 198 else 199 { 200 <span class="text-price">@discountPrice</span> 201 <span class="text-decoration-line-through fs-7"> 202 <span class="text-price">@unitPrice</span> 203 </span> 204 } 205 </p> 206 } 207 </div> 208 209 <div class="g-col-7 g-col-md-3"> 210 @if (!orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount") && !orderIsQuote) 211 { 212 @* Quantity *@ 213 <div class="input-group js-input-group"> 214 <label for="QuantityOrderLine@(orderlineId)" class="visually-hidden">@Translate("Quantity"):</label> 215 <input type="number" id="QuantityOrderLine@(orderlineId)" step="@DoubleToString(stepQty)" min="@DoubleToString(minQty)" max="@DoubleToString(maxQty)" class="form-control text-center swift_quantity-field" onchange="swift.Cart.UpdateCart(event);" value="@DoubleToString(quantity)" name="QuantityOrderLine@(orderlineId)" style="width: 5.5rem;"> 216 <div class="invalid-feedback d-none"> 217 @Translate("Please select a quantity that is dividable by") @stepQty 218 </div> 219 </div> 220 } 221 else 222 { 223 <span>@quantity</span> 224 } 225 </div> 226 </div> 227 228 <div class="g-col-12 g-col-md-4 text-end"> 229 @* Total *@ 230 <span class="h6 mb-0 d-block fs-7 fs-md-6"> 231 <span class="text-price">@priceTotalWithDiscounts</span> 232 </span> 233 @if (orderline.GetDouble("Ecom:Order:OrderLine.TotalDiscount.Price.Value") != 0) 234 { 235 <span class="m-0 d-block fs-8"> 236 <span class="text-price">@discountTotal</span> 237 </span> 238 } 239 </div> 240 241 <div class="g-col-12"> 242 @if (!orderIsQuote) 243 { 244 string clickProductLink = "onclick=\"return removeProductLink('" + @productId + "', '" + @Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(name) + "', '" + @Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(variantText) + "', '" + @unitPriceCurrency + "', '" + @unitPriceWithDiscount + "', '" + @discountAmount + "', '" + @quantity.ToString().Replace(",", ".") + "')\""; 245 246 <a href="@removeFromBasketLink" class="btn btn-link btn-sm p-0 m-0 fs-8" title="@Translate("Remove")" @clickProductLink>@Translate("Remove")</a> 247 } 248 249 <script> 250 function removeProductLink(productId, productName, productVariant, productCurrency, productPrice, productDiscount, productQuantity) { 251 if (typeof gtag !== "undefined") { 252 gtag("event", "remove_from_cart", { 253 currency: productCurrency, 254 value: (parseFloat(productPrice) * parseFloat(productQuantity)), 255 items: [ 256 { 257 item_id: productId, 258 item_name: productName, 259 item_variant: productVariant, 260 currency: productCurrency, 261 price: productPrice, 262 discount: productDiscount, 263 item_list_id: "cart", 264 item_list_name: "Cart", 265 quantity: productQuantity 266 } 267 ] 268 }); 269 } 270 } 271 </script> 272 273 </div> 274 </div> 275 </div> 276 277 @* Bottom border *@ 278 <span class="g-col-12 mt-3"> 279 <span class="d-none d-lg-block border-bottom"></span> 280 </span> 281 </article> 282 } 283 } 284 285 286 @if(Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop) 287 { 288 <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 289 @using Dynamicweb.Ecommerce.Orders 290 291 @* Red lines may be due to variables defined in the parent tempalte - There is no actual error *@ 292 293 @{ 294 295 <div class="align-items-center d-grid d-lg-flex gap-2 justify-content-lg-end mt-lg-4"> 296 297 <a href="Default.aspx?ID=@shopPageId" class="btn btn-link link-secondary text-decoration-none me-lg-3 order-last order-lg-first swift_cartbackbutton"> 298 <span class="d-flex align-items-center justify-content-center position-relative"> 299 <span class="icon-2 me-1 position-absolute position-lg-static start-0"> 300 @ReadFile(iconPath + "chevron-left.svg") 301 </span> 302 <span>@Translate("Continue shopping")</span> 303 </span> 304 </a> 305 306 @if (!anonymousUser && isQuote) 307 { 308 <a href="@($"{Context.Current.Request.Url}&cartcmd=emptycart")" class="btn btn-secondary"> 309 <span class="d-flex align-items-center justify-content-center position-relative"> 310 <span>@Translate("Clear Cart")</span> 311 <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> 312 @ReadFile(iconPath + "trash-2.svg") 313 </span> 314 </span> 315 </a> 316 } 317 318 @if (!string.IsNullOrEmpty(quoteCheckoutLink) && !anonymousUser && !isQuote) 319 { 320 <a href="@quoteCheckoutLink" class="btn btn-secondary"> 321 <span class="d-flex align-items-center justify-content-center position-relative"> 322 <span>@Translate("Request quote")</span> 323 <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> 324 @ReadFile(iconPath + "chevron-right.svg") 325 </span> 326 </span> 327 </a> 328 } 329 330 <a href="@checkoutLink" class="btn btn-primary" id="GoToCheckoutButton"> 331 <span class="d-flex align-items-center justify-content-center position-relative"> 332 <span>@Translate("Checkout")</span> 333 <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> 334 @ReadFile(iconPath + "chevron-right.svg") 335 </span> 336 </span> 337 </a> 338 339 </div> 340 } 341 </text> 342 } 343 344 </form> 345 </div> 346 347 <aside class="g-col-12 g-col-lg-4 position-relative"> 348 <div class="p-3 p-lg-5 pb-lg-4@(theme)"> 349 <header> 350 <h4 class="fs-6 fw-normal mb-2">@Translate("Order summary")</h4> 351 </header> 352 353 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 354 355 @{ 356 double totalPriceWithoutOrderDiscountsFeesAndTaxesValue = GetDouble("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.Price.Value") + GetDouble("Ecom:Order.TotalProductDiscount.Price.Value"); 357 var orderCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(GetString("Ecom:Order.Currency.Code")); 358 string totalPriceWithoutOrderDiscountsFeesAndTaxes = Dynamicweb.Ecommerce.Services.Currencies.Format(orderCurrency, totalPriceWithoutOrderDiscountsFeesAndTaxesValue); 359 360 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 361 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 362 363 bool disableVouchers = Pageview.CurrentParagraph?.Item["DisableVouchers"] != null ? (Boolean)Pageview.CurrentParagraph.Item["DisableVouchers"] : false; 364 disableVouchers = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("CompletedOrderId")) ? true : disableVouchers; 365 366 <div class="d-flex flex-column gap-2 gap-lg-3 pb-3 bottom-0 sticky-receipt theme" id="orderSummaryFooter"> 367 368 @if (!disableVouchers && Pageview.CurrentParagraph?.Item.SystemName != "Swift_QuoteCheckoutApp") 369 { 370 <text> 371 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 372 @using Dynamicweb.Ecommerce.Orders 373 374 @{ 375 string voucherCode = GetString("Ecom:Order.Customer.VoucherCode"); 376 string voucherCodeError = GetString("Ecom:Cart.ValidationError.EcomOrderVoucherCode.ErrorMessage"); 377 string validState = !string.IsNullOrEmpty(voucherCodeError) ? "is-invalid" : string.Empty; 378 bool vouchersAppliedAsDiscounts = false; 379 380 IEnumerable<string> voucherCodes = new List<string>(); 381 Order order = new OrderService().GetById(GetString("Ecom:Order.ID")); 382 383 if (!string.IsNullOrWhiteSpace(voucherCode)) 384 { 385 if (order.VoucherUseType.HasFlag(VoucherUseCategoryType.Discount)) 386 { 387 voucherCodes = voucherCode.Split(new string[] { ",", ";", " " }, StringSplitOptions.RemoveEmptyEntries); 388 vouchersAppliedAsDiscounts = true; 389 } 390 else 391 { 392 voucherCodes = new string[] { voucherCode.Trim() }; 393 } 394 } 395 396 <div class="py-3 border-top" id="orderVoucherForm"> 397 <form method="post" id="VoucherForm"> 398 <div class="input-group input-primary-button-group has-validation"> 399 <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;"> 400 <button class="btn btn-sm btn-primary d-inline-flex align-items-center justify-content-center" type="submit" id="EcomOrderVoucherApply" style="min-width: 100px;"> 401 <span>@Translate("Apply")</span> 402 </button> 403 <div class="invalid-feedback"> 404 @voucherCodeError 405 </div> 406 </div> 407 <input type="hidden" name="EcomOrderVoucherCode" id="EcomOrderVoucherCode" value="@voucherCode"> 408 <label for="EcomOrderVoucherCodeField" class="visually-hidden">@Translate("Add voucher here")</label> 409 </form> 410 411 @if (!string.IsNullOrWhiteSpace(voucherCode)) 412 { 413 <div class="d-flex flex-wrap gap-2 pt-3"> 414 @foreach (string code in voucherCodes) 415 { 416 <form method="post"> 417 @{ 418 Dynamicweb.Ecommerce.Orders.Vouchers.Voucher vouch = Dynamicweb.Ecommerce.Services.Vouchers.GetVoucherByCode(code); 419 string voucherValue = string.Empty; 420 if (vouch != null && !vouch.DateUsed.HasValue) { 421 voucherValue = voucherCode.Replace(code+",", "").Replace(","+code, "").Replace(code, ""); 422 } 423 <input type="hidden" name="EcomOrderVoucherCode" value="@voucherValue"> 424 } 425 <span class="badge fw-normal d-inline-flex align-items-center justify-content-center opacity-50 opacity-100-hover" style="background-color:var(--swift-foreground-color);color:var(--swift-background-color);"> 426 <span class="icon-2"> 427 @ReadFile("/Files/Templates/Designs/Swift/Assets/icons/tag.svg") 428 </span> 429 <span class="mx-2">@code</span> 430 <button type="submit" class="text-reset bg-transparent border-0 p-0" aria-label="@Translate("Remove voucher")" id="RemoveVoucherButton"> 431 <span class="icon-2"> 432 @ReadFile("/Files/Templates/Designs/Swift/Assets/icons/x.svg") 433 </span> 434 </button> 435 </span> 436 </form> 437 } 438 </div> 439 } 440 </div> 441 } 442 443 </text> 444 } 445 446 <div class="fs-8 border-top pt-2 pt-lg-3"> 447 @* Subtotal *@ 448 <div class="d-flex justify-content-between fw-bold"> 449 <span>@Translate("Subtotal")</span> 450 <span class="text-end"> 451 <span class="d-block"> 452 @if (GetDouble("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.Price.Value") != totalPriceWithoutOrderDiscountsFeesAndTaxesValue) 453 { 454 <span class="text-price fw-normal text-decoration-line-through">@GetString("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.PriceFormatted")</span> 455 } 456 <span class="text-price">@totalPriceWithoutOrderDiscountsFeesAndTaxes</span> 457 </span> 458 459 @if (!neverShowVat && showPricesWithVat == "false") 460 { 461 <span class="fs-8 fw-normal d-block">@Translate("Excl. VAT")</span> 462 } 463 else if (!neverShowVat) 464 { 465 <span class="fs-8 fw-normal d-block">@Translate("Incl. VAT")</span> 466 } 467 </span> 468 </div> 469 470 @* Discounts (only order discounts) *@ 471 @foreach (LoopItem orderline in GetLoop("OrderLines")) 472 { 473 bool isDiscount = orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount"); 474 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 475 bool isOrderAmountDiscount = orderline.GetInteger("Ecom:Order:OrderLine.Type") == 1 && !isProductIdOrNumber; 476 if (isDiscount && isOrderAmountDiscount) 477 { 478 <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> 479 } 480 } 481 482 @* Delivery *@ 483 @if (!string.IsNullOrEmpty(GetString("Ecom:Order.ShippingMethodID"))) 484 { 485 if (GetDouble("Ecom:Order.ShippingFee.Price.Value") != 0.0) 486 { 487 <div class="d-flex justify-content-between"> 488 <span>@Translate("Delivery")</span> 489 <span>@GetString("Ecom:Order.ShippingFee.PriceFormatted")</span> 490 </div> 491 } 492 } 493 else 494 { 495 <div class="d-flex justify-content-between"> 496 <span>@Translate("Delivery")</span> 497 <span>@Translate("Calculated in next step")</span> 498 </div> 499 } 500 501 @* Payment *@ 502 @if (!string.IsNullOrEmpty(GetString("Ecom:Order.PaymentMethodID"))) 503 { 504 if (GetDouble("Ecom:Order.PaymentFee.Price.Value") != 0) 505 { 506 <div class="d-flex justify-content-between"> 507 <span>@Translate("Payment")</span> 508 <span class="text-price">@GetString("Ecom:Order.PaymentFee.PriceFormatted")</span> 509 </div> 510 } 511 } 512 else 513 { 514 <div class="d-flex justify-content-between"> 515 <span>@Translate("Payment")</span> 516 <span>@Translate("Calculated in next step")</span> 517 </div> 518 } 519 520 @* Taxes *@ 521 @if (GetDouble("Ecom:Order.Taxes.Total.Price.Value") != 0) 522 { 523 <div class="d-flex justify-content-between mb-2"> 524 <span>@Translate("Sales tax")</span> 525 <span>@GetString("Ecom:Order.Taxes.Total.PriceFormatted")</span> 526 </div> 527 } 528 </div> 529 <div class="fs-8 border-top pt-2 pt-lg-3"> 530 <div class="d-flex justify-content-between fs-6 fw-bold"> 531 <span>@Translate("Total")</span> 532 @if (!neverShowVat && showPricesWithVat == "false") 533 { 534 <span class="text-price text-end"> 535 <span class="fs-5 d-block">@GetString("Ecom:Order.Price.PriceFormatted")</span> 536 <span class="fs-8 fw-normal d-block">@Translate("Excl. VAT")</span> 537 </span> 538 } 539 else if (!neverShowVat && showPricesWithVat == "true") 540 { 541 <span class="text-price text-end"> 542 <span class="fs-5 d-block">@GetString("Ecom:Order.Price.PriceFormatted")</span> 543 <span class="fs-8 fw-normal d-block">@Translate("Incl. VAT")</span> 544 </span> 545 } 546 else 547 { 548 <span class="text-price fs-5">@GetString("Ecom:Order.Price.PriceFormatted")</span> 549 } 550 </div> 551 552 @if (!neverShowVat) 553 { 554 <div class="d-flex justify-content-between"><span>@Translate("VAT")</span><span class="text-price">@GetString("Ecom:Order.Price.VATFormatted")</span></div> 555 if (showPricesWithVat == "false") 556 { 557 <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> 558 } 559 } 560 561 @if (GetDouble("Ecom:Order.TotalDiscount.Price.Value") != 0) 562 { 563 <div class="d-flex justify-content-between"><span>@Translate("Discount")</span><span class="text-price">@GetString("Ecom:Order.TotalDiscount.PriceFormatted")</span></div> 564 } 565 </div> 566 </div> 567 } 568 569 570 @if(Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile || Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet) 571 { 572 <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 573 @using Dynamicweb.Ecommerce.Orders 574 575 @* Red lines may be due to variables defined in the parent tempalte - There is no actual error *@ 576 577 @{ 578 579 <div class="align-items-center d-grid d-lg-flex gap-2 justify-content-lg-end mt-lg-4"> 580 581 <a href="Default.aspx?ID=@shopPageId" class="btn btn-link link-secondary text-decoration-none me-lg-3 order-last order-lg-first swift_cartbackbutton"> 582 <span class="d-flex align-items-center justify-content-center position-relative"> 583 <span class="icon-2 me-1 position-absolute position-lg-static start-0"> 584 @ReadFile(iconPath + "chevron-left.svg") 585 </span> 586 <span>@Translate("Continue shopping")</span> 587 </span> 588 </a> 589 590 @if (!anonymousUser && isQuote) 591 { 592 <a href="@($"{Context.Current.Request.Url}&cartcmd=emptycart")" class="btn btn-secondary"> 593 <span class="d-flex align-items-center justify-content-center position-relative"> 594 <span>@Translate("Clear Cart")</span> 595 <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> 596 @ReadFile(iconPath + "trash-2.svg") 597 </span> 598 </span> 599 </a> 600 } 601 602 @if (!string.IsNullOrEmpty(quoteCheckoutLink) && !anonymousUser && !isQuote) 603 { 604 <a href="@quoteCheckoutLink" class="btn btn-secondary"> 605 <span class="d-flex align-items-center justify-content-center position-relative"> 606 <span>@Translate("Request quote")</span> 607 <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> 608 @ReadFile(iconPath + "chevron-right.svg") 609 </span> 610 </span> 611 </a> 612 } 613 614 <a href="@checkoutLink" class="btn btn-primary" id="GoToCheckoutButton"> 615 <span class="d-flex align-items-center justify-content-center position-relative"> 616 <span>@Translate("Checkout")</span> 617 <span class="icon-2 ms-1 position-absolute position-lg-static end-0"> 618 @ReadFile(iconPath + "chevron-right.svg") 619 </span> 620 </span> 621 </a> 622 623 </div> 624 } 625 </text> 626 } 627 628 </div> 629 </aside> 630 </div> 631