Error executing template "Designs/Swift/eCom7/CartV2/Step/SR_InvoicesManagementCenterPayment.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_f055495dfe1c4ba9b1d19bd86d33d5d8.Execute() in E:\Domains\Sites\portal.keystonerv.com\Files\Templates\Designs\Swift\eCom7\CartV2\Step\SR_InvoicesManagementCenterPayment.cshtml:line 138
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.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
2 @using Dynamicweb
3 @using System.IO
4 @using Dynamicweb.Core
5 @using Dynamicweb.Ecommerce.Orders
6 @functions
7 {
8 private void SetDefaultMethods()
9 {
10 LoopItem shippingMethod = GetLoop("Shippingmethods").FirstOrDefault();
11 if (shippingMethod == null || shippingMethod.GetString("Ecom:Cart.Shippingmethod.ID") == GetString("Ecom:Order.ShippingMethodID"))
12 {
13 return;
14 }
15
16 Order cart = Dynamicweb.Ecommerce.Services.Orders.GetById(GetString("Ecom:Order.ID"));
17 cart.ShippingMethodId = shippingMethod.GetString("Ecom:Cart.Shippingmethod.ID");
18 cart.ShippingMethod = shippingMethod.GetString("Ecom:Cart.Shippingmethod.Name");
19
20 // Set default payment based on shopping cart app if user did not selected one
21 if (Context.Current.Request["EcomCartPaymethodID"] == null)
22 {
23 LoopItem paymentMethod = GetLoop("Paymethods").FirstOrDefault();
24
25 if (paymentMethod != null || paymentMethod.GetString("Ecom:Cart.Paymethod.ID") != GetString("Ecom:Order.ShippingMethodID"))
26 {
27 cart.PaymentMethodId = paymentMethod.GetString("Ecom:Cart.Paymethod.ID");
28 cart.PaymentMethod = paymentMethod.GetString("Ecom:Cart.Paymethod.Name");
29 }
30 }
31
32 Dynamicweb.Ecommerce.Services.Orders.Save(cart);
33 string redirect = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(Pageview.Page.ID);
34 Context.Current.Response.Redirect(redirect);
35 }
36
37 private void RedirectToCheckout(bool needsPayment)
38 {
39 if (!needsPayment) return;
40
41 List<LoopItem> payMethods = GetLoop("Paymethods");
42 bool isSinglePayment = payMethods.Count == 1;
43
44 if (!isSinglePayment) return;
45
46 bool hasSavedCards = GetLoop("SavedCards").Any();
47
48 if (hasSavedCards) return;
49
50 Order cart = Dynamicweb.Ecommerce.Services.Orders.GetById(GetString("Ecom:Order.ID"));
51 int nextStepIndex = cart.CartV2StepIndex + 1;
52 cart.PaymentMethodId = payMethods.FirstOrDefault().GetString("Ecom:Cart.Paymethod.ID");
53 cart.PaymentMethod = payMethods.FirstOrDefault().GetString("Ecom:Cart.Paymethod.Name");
54 Dynamicweb.Ecommerce.Services.Orders.Save(cart);
55 string redirect = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(Pageview.Page.ID) + "?CartV2.GotoStep" + nextStepIndex + "=true";
56 Context.Current.Response.Redirect(redirect);
57 }
58 }
59 @{
60 SetDefaultMethods();
61 bool needsPayment = GetDouble("Ecom:Order.OrderLines.TotalPriceWithoutSymbol") > 0;
62 RedirectToCheckout(needsPayment);
63 }
64 <div class="grid gap-0">
65 <div class="cart g-col-12 g-col-lg-8 py-3 py-lg-5 pe-lg-5 order-last order-lg-first">
66 <form name="ordersubmit" id="ordersubmit" method="post" autocomplete="off">
67
68 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
69 @using Dynamicweb
70 @using System.IO
71
72 @{
73 string logoLink = Pageview.CurrentParagraph?.Item["LogoLink"] != null ? Pageview.CurrentParagraph.Item["LogoLink"].ToString() : string.Empty;
74
75 string logoImage = Pageview.CurrentParagraph?.Item["Logo"] != null ? Pageview.CurrentParagraph.Item["Logo"].ToString() : string.Empty;
76 string title = Pageview.CurrentParagraph?.Item["Title"] != null ? Pageview.CurrentParagraph.Item["Title"].ToString() : Pageview.Area.Name;
77
78 string maxWidth = Pageview.CurrentParagraph?.Item["MaxWidth"] != null ? "max-width: " + Pageview.CurrentParagraph.Item["MaxWidth"].ToString() + "px" : string.Empty;
79 maxWidth = maxWidth == "max-width: 0px" ? string.Empty : maxWidth;
80 }
81
82 <div class="mb-4 text-center">
83 @if (!string.IsNullOrWhiteSpace(logoLink))
84 {
85 @:<a href="@logoLink" class="text-decoration-none" title="@Translate("Leave checkout")">
86 }
87
88 @if (logoImage != "")
89 {
90 if (Path.GetExtension(logoImage).ToLower() == ".svg")
91 {
92 <div class="icon-auto" style="@maxWidth">
93 @ReadFile(logoImage)
94 </div>
95 }
96 else
97 {
98 string imageWidth = Pageview.CurrentParagraph.Item["MaxWidth"] != null ? Pageview.CurrentParagraph.Item["MaxWidth"].ToString() : "400";
99 string imagePath = "/Admin/Public/GetImage.ashx?width=" + imageWidth + "&image=" + logoImage;
100
101 <picture class="mx-auto d-block">
102 <img src="@logoImage" alt="@title" style="@maxWidth">
103 </picture>
104 }
105 }
106 else
107 {
108 <div class="fs-3 p-0">@title</div>
109 }
110
111 @if (!string.IsNullOrWhiteSpace(logoLink))
112 {
113 @:</a>
114 }
115 </div>
116
117
118 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
119 @using Dynamicweb.Ecommerce.Orders
120
121 @if (GetLoop("ValidationErrors").Count() != 0)
122 {
123 <div class="alert alert-warning" role="alert">
124 <ul class="m-0 list-unstyled">
125 @foreach (LoopItem item in GetLoop("ValidationErrors"))
126 {
127 <li>@item.GetValue("Ecom:Cart.ValidationError.ErrorMessage")</li>
128 }
129 </ul>
130 </div>
131 }
132
133
134 @* Logic to remove the voucher code error, when going to next step in checkout *@
135 @{
136 string voucherCodeForErrorCheck = GetString("Ecom:Order.Customer.VoucherCode");
137 Order orderForErrorCheck = new OrderService().GetById(GetString("Ecom:Order.ID"));
138 voucherCodeForErrorCheck = orderForErrorCheck.VoucherUseType == VoucherUseCategoryType.None ? string.Empty : voucherCodeForErrorCheck;
139 }
140
141 <input type="hidden" name="EcomOrderVoucherCode" value="@voucherCodeForErrorCheck">
142
143
144 <div class="mt-4">
145 @if (needsPayment)
146 {
147 <h3 class="fs-6 fw-normal mb-0">@Translate("Select payment")</h3>
148 <p class="fs-8 mb-3">@Translate("All transactions are encrypted")</p>
149 <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
150
151 @{
152 string paymentErrorMessage = GetString("Ecom:Cart.ValidationError.EcomCartPaymethodId.ErrorMessage");
153
154 <div class="list-group" id="PaymentMethodsGroup">
155 @foreach (LoopItem method in GetLoop("Paymethods"))
156 {
157 <label class="list-group-item list-group-item-action">
158 <dl class="grid gap-1 gap-sm-3 mb-0">
159 <dt class="g-col-8 g-col-sm-4 fw-normal">
160 <div class="form-check">
161 @{
162 string paymentMethodId = GetString("Ecom:Order.PaymentMethodID");
163 string paymentMethodIdSaved = method.GetString("Ecom:Cart.Paymethod.ID");
164 }
165 <input class="form-check-input" type="radio" name="EcomCartPaymethodID" id="EcomCartPaymentmethodID_@method.GetString("Ecom:Cart.Paymethod.ID")" @if (String.Equals(paymentMethodId, paymentMethodIdSaved)) { <text> checked="checked" </text> } value="@method.GetString("Ecom:Cart.Paymethod.ID")" onchange="submitForm()">
166 <span class="form-check-label">@method.GetString("Ecom:Cart.Paymethod.Name")</span>
167 </div>
168 </dt>
169 <dd class="g-col-12 g-col-sm-7 order-2 order-sm-1 mb-0">
170 @{
171 string imagePath = Dynamicweb.Context.Current.Server.MapPath(method.GetString("Ecom:Cart.Paymethod.Icon.Clean"));
172
173 if (File.Exists(imagePath))
174 {
175 <span class="m-0 d-block" style="height: 1.5rem; width: 100%; background: url('@method.GetString("Ecom:Cart.Paymethod.Icon.Clean")') no-repeat left center; background-size: contain;"></span>
176 }
177 else
178 {
179 <span class="fs-8 lh-1">@method.GetString("Ecom:Cart.Paymethod.Description")</span>
180 }
181 }
182
183 </dd>
184 <dd class="g-col-4 g-col-sm-1 order-1 order-sm-2 mb-0 text-end">
185 @if (!method.GetBoolean("Ecom:Cart.Paymethod.Price.IsZero"))
186 {
187 <span class="text-price">@method.GetString("Ecom:Cart.Paymethod.Price")</span>
188 }
189 </dd>
190 </dl>
191 </label>
192 }
193 @paymentErrorMessage
194 </div>
195
196 LoopItem selectedPaymentMethodWithSavedCardSupport = GetLoop("Paymethods").FirstOrDefault(p => p.GetBoolean("Ecom:Cart.Paymethod.IsSelected") && p.GetBoolean("Ecom:Cart.Paymethod.SupportSavedCard") && Pageview.User != null);
197 if (selectedPaymentMethodWithSavedCardSupport != null)
198 {
199 bool cardIsSaved = !string.IsNullOrEmpty(GetString("Ecom:Order.SavedCardName"));
200 string cardIsSavedValue = cardIsSaved ? "true" : string.Empty;
201 string savedCardName = "";
202
203 <div class="list-group" id="SavedCardsGroup">
204 <h4 class="fs-6 fw-normal mb-0 mt-4">@Translate("Saved Cards")</h4>
205 <p class="fs-8 mb-3">@Translate("Pay with a saved card")</p>
206
207 @foreach (LoopItem card in GetLoop("SavedCards"))
208 {
209 savedCardName = !card.GetBoolean("Ecom:SavedCard.IsSelected") ? card.GetString("Ecom:SavedCard.Name") : savedCardName;
210
211 <label class="list-group-item list-group-item-action">
212 <div class="form-check fw-normal">
213 <input class="form-check-input" type="radio" name="EcomCartSavedCardID" id="EcomSavedCardID_@card.GetString("Ecom:SavedCard.ID")" value="@card.GetString("Ecom:SavedCard.ID")" checked="@card.GetBoolean("Ecom:SavedCard.IsSelected")" data-card-name="@card.GetString("Ecom:SavedCard.Name")" onchange="selectSavedCard(this)">
214 <span class="form-check-label">@card.GetString("Ecom:SavedCard.Name")</span>
215 </div>
216 </label>
217 }
218
219 <label class="list-group-item list-group-item-action">
220 <dl class="grid gap-0 gap-sm-3 align-items-center mb-0">
221 <dt class="g-col-4 fw-normal">
222 <div class="form-check">
223 <input class="form-check-input" type="radio" name="EcomCartSavedCardID" id="SaveNewCard" value="" checked="@cardIsSavedValue" onchange="selectNewCard(this)">
224 <span class="form-check-label fst-italic">@Translate("Save a new card")</span>
225 </div>
226 </dt>
227 <dd class="g-col-6 mb-0">
228 <input type="checkbox" class="d-none" name="EcomOrderSavedCardCreate" id="EcomOrderSavedCardCreate" value="true" checked="@cardIsSavedValue">
229 <input type="text" class="form-control" id="NewSavedCardName" value="@GetString("Ecom:Order.SavedCardName")" onchange="document.getElementById('MySavedCardName').value=this.value" placeholder="@Translate("New saved card name")">
230 </dd>
231 </dl>
232 </label>
233
234 <input type="hidden" name="EcomOrderSavedCardName" id="MySavedCardName" value="@savedCardName" />
235 </div>
236 }
237 }
238
239 <script>
240 function selectSavedCard(element) {
241 let cardName = element.getAttribute('data-card-name');
242
243 resetRadioButton(element);
244 updateSavedCardName(cardName);
245 updateNewCardValue(false);
246 }
247
248 function selectNewCard(element) {
249 resetRadioButton(element);
250 updateSavedCardName("");
251 updateNewCardValue(true);
252 }
253
254 function resetRadioButton(element) {
255 let radioList = document.querySelector("input[name='EcomCartSavedCardID']");
256 for (let i = 0; i < radioList.length; i++) {
257 if (radioList[i].checked && radioList[i].id !== element.id) radioList[i].checked = false;
258 }
259 }
260
261 function updateSavedCardName(value) {
262 let savedCardNameField = document.querySelector("#MySavedCardName");
263 if (savedCardNameField) {
264 savedCardNameField.value = value;
265 }
266 }
267
268 function updateNewCardValue(value) {
269 let newCardField = document.querySelector("#EcomOrderSavedCardCreate");
270 if (newCardField) {
271 newCardField.checked = value;
272 }
273 }
274 </script>
275 </text>
276 }
277 else
278 {
279 string dummyPaymentId = Converter.ToString(Pageview.CurrentParagraph.Item["DummyPayment"]);
280 <div class="alert alert-success" role="alert">
281 @Translate("Your order total is $ 0.00. Click 'Pay Now' button to confirm your payment.")
282 </div>
283
284 <input type="hidden" name="EcomCartPaymethodID" value="@dummyPaymentId"/>
285 }
286 </div>
287
288 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
289
290 @{
291 string iconPathInvoiceManagementCenterStepsNavigation = "/Files/Templates/Designs/Swift/Assets/icons/";
292 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Pageview.GlobalTags.GetTagByName("Global:LiveIntegration.IsWebServiceConnectionAvailable")?.Value ?? "true");
293 string erpDownCartBehavior = Pageview.CurrentParagraph.Item["ErpDownCartBehavior"]?.ToString() ?? "none";
294
295 <div class="mt-4 d-flex flex-column flex-md-row justify-content-end gap-3 mt-lg-4">
296 <a href="@Pageview.CurrentParagraph.Item["InvoicesManagementCenterPageLink"]" class="btn btn-link link-secondary text-decoration-none order-last order-md-first">
297 <div class="d-flex align-items-center justify-content-center position-relative">
298 <span class="icon-2 me-1 position-absolute position-md-static start-0">
299 @ReadFile(iconPathInvoiceManagementCenterStepsNavigation + "chevron-left.svg")
300 </span>
301 <span>@Translate("Back")</span>
302 </div>
303 </a>
304
305 @if (!(isErpConnectionDown && erpDownCartBehavior == "disable"))
306 {
307 <button type="submit" name="@GetString("CartV2.NextStepButtonName")" id="@GetString("CartV2.NextStepButtonName")" class="btn btn-primary order-first order-md-last">
308 <div class="d-flex align-items-center justify-content-center position-relative">
309 <span>@Translate("Pay now")</span>
310 <span class="icon-2 ms-1 position-absolute position-md-static end-0">
311 @ReadFile(iconPathInvoiceManagementCenterStepsNavigation + "chevron-right.svg")
312 </span>
313 </div>
314 </button>
315 }
316 else
317 {
318 <button class="btn btn-primary pe-none disabled">@Translate("Payment is temporarily disabled")</button>
319 }
320
321 <script>
322 if ( window.history.replaceState ) {
323 window.history.replaceState( null, null, window.location.href );
324 }
325 </script>
326 </div>
327 }
328
329
330 <input type="hidden" id="CurrentStep" />
331 </form>
332 </div>
333
334 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
335 @using Dna.Keystone.Vin
336
337 @if(GetString("Ecom:OrderContext.ID").Equals(Dna.PaymentLedgers.Constants.OrderContext))
338 {
339 <text>@using Dynamicweb.Ecommerce.Orders
340 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
341
342 @functions
343 {
344 private class TypeTotal
345 {
346 public string Type { get; set; }
347 public string Currency { get; set; }
348 public double Amount { get; set; }
349 }
350
351 private static List<TypeTotal> SumTotals(IEnumerable<LoopItem> orderlines)
352 {
353 return orderlines.GroupBy(ol => ol.GetString("Ecom:Order:OrderLine.ProductName").ToLower(),
354 (k, total) => new TypeTotal()
355 {
356 Type = k,
357 Currency = total.FirstOrDefault().GetString("Ecom:Order:OrderLine.Price.Currency.Symbol"),
358 Amount = total.Sum(x => x.GetDouble("Ecom:Order:OrderLine.Price.Price.Value"))
359 }).ToList();
360 }
361
362 private static string GetTotalValue(IEnumerable<TypeTotal> total, string type)
363 {
364 TypeTotal typeTotal = total.FirstOrDefault(t => t.Type.Equals(type, StringComparison.InvariantCultureIgnoreCase));
365
366 return typeTotal == null ? "" : $"{typeTotal.Currency} {typeTotal.Amount:0.00}";
367 }
368 }
369
370 @{
371 List<LoopItem> discounts = GetLoop("OrderLines").Where(o => o.GetBoolean("Ecom:Order:OrderLine.IsDiscount") && o.GetInteger("Ecom:Order:OrderLine.Type") == 1).ToList();
372 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower();
373 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat);
374
375 List<TypeTotal> totals = SumTotals(GetLoop("OrderLines").Where(o => o.GetInteger("Ecom:Order:OrderLine.Type") != (int)OrderLineType.Tax).ToList());
376
377 string summarySidebarClass = string.IsNullOrEmpty(GetString("Ecom:Order.Completed")) ? "g-col-12 g-col-lg-4 position-relative py-2 py-lg-5 ps-lg-5 border-start px-3 px-lg-0 mx-n3 mx-lg-0" : "";
378 }
379
380 <div class="summary-sidebar @summarySidebarClass" id="summarySidebar">
381 <div class="position-relative">
382
383 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
384
385 @{
386 string iconPath = "/Files/Icons/";
387 }
388
389 <button class="toggle-order-summary btn text-reset w-100 d-block d-lg-none px-0" type="button" data-bs-toggle="collapse" data-bs-target="#orderSummary" aria-expanded="false" aria-controls="orderSummary" id="OrderSummaryToggleButton">
390 <span class="d-flex align-items-center justify-content-between">
391 <span class="d-flex align-items-center gap-2">
392 <span class="fs-7 lh-1">
393 <span class="toggle-order-summary-text" id="OrderSummaryToggleButtonLabel">@Translate("Show order summary")</span>
394 </span>
395 <span class="icon-2" id="OrderSummaryToggleButtonIcon" style="transition: all 0.25s ease-in-out;">
396 @ReadFile(iconPath + "chevron-down.svg")
397 </span>
398 </span>
399 <span class="fw-bold">
400 <span class="text-price">@GetString("Ecom:Order.Price")</span>
401 </span>
402 </span>
403 </button>
404
405 <script>
406 const orderSummaryToggleButton = document.getElementById("OrderSummaryToggleButton");
407 const orderSummaryToggleButtonLabel = document.getElementById("OrderSummaryToggleButtonLabel");
408 const orderSummaryToggleButtonIcon = document.getElementById("OrderSummaryToggleButtonIcon");
409 const orderSummaryToggleText = '@Translate("Show order summary")';
410
411 orderSummaryToggleButton.addEventListener('click', function handleClick() {
412 if (orderSummaryToggleButtonLabel.textContent.toLowerCase().includes(orderSummaryToggleText.toLowerCase())) {
413 orderSummaryToggleButtonLabel.textContent = '@Translate("Hide order summary")';
414 orderSummaryToggleButtonIcon.classList.add("rotate-180");
415 } else {
416 orderSummaryToggleButtonLabel.textContent = orderSummaryToggleText;
417 orderSummaryToggleButtonIcon.classList.remove("rotate-180");
418 }
419 });
420 </script>
421
422
423
424 <div class="d-lg-block h-lg-auto visible-lg-visible pb-2 pb-md-0 collapse" id="orderSummary">
425 <div class="d-flex flex-column gap-3 position-relative mb-2" id="orderSummaryList" style="overflow-x: hidden; overflow-y: hidden;">
426 @foreach (LoopItem orderline in GetLoop("OrderLines")) {
427 string name = orderline.GetString("Ecom:Order:OrderLine.ProductName");
428 string priceTotalWithDiscounts = orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.PriceFormatted");
429 string discountTotal = orderline.GetString("Ecom:Order:OrderLine.TotalDiscount.PriceFormatted");
430 bool isProduct = orderline.GetBoolean("Ecom:Order:OrderLine.IsProduct");
431
432 if (isProduct)
433 {
434 <article class="grid grid-12">
435 <div class="g-col-12">
436 <div class="grid grid-12">
437 <div class="g-col-6 grid grid-6 gap-0">
438 <div class="g-col-6">
439 @* Title *@
440 <h3 class="h6 fs-7 mb-0">@name: @orderline.GetString("Ecom:Order:OrderLine.ProductNumber")</h3>
441 </div>
442 </div>
443 <div class="g-col-6 text-end">
444 @* Total *@
445 <span class="h6 mb-0 d-block fs-7">
446 <span class="text-price">@priceTotalWithDiscounts</span>
447 </span>
448 @if (orderline.GetDouble("Ecom:Order:OrderLine.TotalDiscount.Price.Value") != 0)
449 {
450 <span class="m-0 d-block fs-8">
451 <span class="text-price">@discountTotal</span>
452 </span>
453 }
454 </div>
455 </div>
456 </div>
457 </article>
458 }
459 }
460 <div class="btn btn-primary position-absolute bottom-0 mb-3 btn-sm d-none" style="width: auto; left: 50%; transform: translateX(-50%);" id="scrollToViewMoreButton">@Translate("Scroll to view more")</div>
461 </div>
462
463 <div id="orderSummaryFooter">
464 @if (discounts.Any() || GetDouble("Ecom:Order.PaymentFee.Price.Value") != 0 || GetDouble("Ecom:Order.Taxes.Total.Price.Value") != 0) {
465 <div class="fs-8 pt-2 border-top">
466 @* Discounts (only order discounts) *@
467 @foreach (LoopItem orderline in discounts)
468 {
469 <div class="d-flex justify-content-between mb-2"><span>@orderline.GetString("Ecom:Order:OrderLine.ProductName")</span><span>@orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.PriceFormatted")</span></div>
470 }
471
472 @* Payment *@
473 @if (GetDouble("Ecom:Order.PaymentFee.Price.Value") != 0)
474 {
475 <div class="d-flex justify-content-between mb-2">
476 <span>@Translate("Payment")</span>
477 <span class="text-price">@GetString("Ecom:Order.PaymentFee.PriceFormatted")</span>
478 </div>
479 }
480
481 @* Sales tax *@
482 @if (!(showPricesWithVat == "false" && !neverShowVat))
483 {
484 if (GetDouble("Ecom:Order.Taxes.Total.Price.Value") != 0)
485 {
486 <div class="d-flex justify-content-between mb-2">
487 <span>@Translate("Sales tax")</span>
488 <span>@GetString("Ecom:Order.Taxes.Total.PriceFormatted")</span>
489 </div>
490 }
491 }
492 </div>
493 }
494
495 <div class="fs-8 pt-2 border-top">
496 @if(!string.IsNullOrEmpty(GetTotalValue(totals, "Invoice"))) {
497 <div class="d-flex justify-content-between mb-2">
498 <span>@Translate("Total of Invoices")</span>
499 <span class="text-price">@GetTotalValue(totals, "Invoice")</span>
500 </div>
501 }
502
503 @if(!string.IsNullOrEmpty(GetTotalValue(totals, "Proforma"))) {
504 <div class="d-flex justify-content-between mb-2">
505 <span>@Translate("Total of Proforma")</span>
506 <span class="text-price">@GetTotalValue(totals, "Proforma")</span>
507 </div>
508 }
509
510 @if(!string.IsNullOrEmpty(GetTotalValue(totals, "Credit"))) {
511 <div class="d-flex justify-content-between mb-2">
512 <span>@Translate("Total of Credit Memos")</span>
513 <span class="text-price">@GetTotalValue(totals, "Credit")</span>
514 </div>
515 }
516
517 @if(!string.IsNullOrEmpty(GetTotalValue(totals, "Discount"))) {
518 <div class="d-flex justify-content-between mb-2">
519 <span>@Translate("Discounts")</span>
520 <span class="text-price">@GetTotalValue(totals, "Discount")</span>
521 </div>
522 }
523
524 @if(!string.IsNullOrEmpty(GetTotalValue(totals, "Discount"))) {
525 <div class="d-flex justify-content-between mb-2">
526 <span>@Translate("Discounts")</span>
527 <span class="text-price">@GetTotalValue(totals, "Discount")</span>
528 </div>
529 }
530 </div>
531
532 <div class="fs-8 pt-3 border-top">
533 <div class="d-flex justify-content-between mb-2 fs-6 fw-bold"><span>@Translate("Total")</span><span class="text-price fs-5">@GetString("Ecom:Order.Price.PriceFormatted")</span></div>
534 </div>
535 </div>
536 </div>
537 </div>
538 </div>
539 </text>
540 }
541 else
542 {
543 <div class="g-col-12 g-col-lg-4 py-2 p-3 p-lg-4 p-xl-5" id="summarySidebar">
544
545 @*START CUSTOM CODE*@
546 @{
547 var summarySidebarSelectedVinRow = Dna.Keystone.Vin.Helpers.GetSelectedVinRow();
548 var vinLookUpServicePageId = GetPageIdByNavigationTag("VinLookupServicePage");
549 var vinLookupServicePageUrl = vinLookUpServicePageId > 0 ? $"Default.aspx?ID={vinLookUpServicePageId}&{Constants.Request.CloseModalAfterSelect}=True" : "";
550
551 <header class="g-col-12 cartCurrentVehicle">
552 @if (summarySidebarSelectedVinRow != null)
553 {
554 var unitDetailPageId = GetPageIdByNavigationTag("UnitDetails");
555 var unitDetailPageFriendlyUrl = unitDetailPageId > 0 ? Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={unitDetailPageId}") : string.Empty;
556
557 <h4 class="fs-6 fw-bold">@Translate("Current Vehicle")</h4>
558
559 <dl class="d-flex flex-row flex-wrap gap-3 align-items-center fs-8 border-bottom pt-2 pt-lg-3 pb-2 pb-lg-3">
560
561 <dt>@Translate("VIN")</dt>
562 <dd class="mb-0 me-2">
563 @if (!string.IsNullOrEmpty(unitDetailPageFriendlyUrl))
564 {
565 var url = $"{unitDetailPageFriendlyUrl}?vq={summarySidebarSelectedVinRow.Vin}";
566 <a href="@url" target="_blank">@summarySidebarSelectedVinRow.Vin</a>
567 }
568 else
569 {
570 @summarySidebarSelectedVinRow.Vin
571 }
572 </dd>
573
574 <dt>@Translate("Make")</dt>
575 <dd class="mb-0 me-2">@summarySidebarSelectedVinRow.Make</dd>
576
577 <dt>@Translate("Model")</dt>
578 <dd class="mb-0 me-2">@summarySidebarSelectedVinRow.Model</dd>
579
580 <dt>@Translate("Warranty")</dt>
581 <dd class="mb-0 me-2">@(summarySidebarSelectedVinRow.IsWarrantyValid() ? Translate("Warranty Active") : Translate("Warranty Expired"))</dd>
582
583 <dt>@Translate("Retail Sold")</dt>
584 <dd class="mb-0 me-2">@Dna.Keystone.Vin.Helpers.GetDateFormatted(summarySidebarSelectedVinRow.ShipDate)</dd>
585
586 <dt>@Translate("Model Year")</dt>
587 <dd class="mb-0 me-2">@summarySidebarSelectedVinRow.ModelYear</dd>
588 </dl>
589 }
590 else
591 {
592 <h4 class="fs-6 fw-bold text-danger">@Translate("Stock Order")</h4>
593
594 <div class="d-flex flex-row flex-wrap gap-3 align-items-center fs-8 border-bottom pt-0 pb-2 pb-lg-3 mb-3">
595 <div class="w-100 text-left">
596 <button class="rowAddVinButton btn p-0 text-uppercase" onclick="CurrentVehicle.OpenVinLookupModal();">
597 <span class="icon-3 pe-none">
598 @ReadFile("/Files/Templates/Designs/Swift/Assets/icons/" + "add-vin-asset.svg")
599 </span>
600 <span>@Translate("Add Vin")</span>
601 </button>
602 </div>
603 </div>
604 }
605 </header>
606
607 <div class="modal fade js-product" id="DynamicModal" tabindex="-1" aria-hidden="true">
608 <div class="modal-dialog modal-dialog-centered modal-md">
609 <div class="modal-content theme light" id="DynamicModalContent">
610 @* The content here comes from an external request *@
611 </div>
612 </div>
613 </div>
614
615 <script id="CurrentVehicleVinLookupModal" type="text/html">
616 <div class="modal-dialog modal-xl modal-fullscreen-xl-down">
617 <div class="modal-content">
618 <div class="modal-header">
619 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="@Translate("Close")"></button>
620 </div>
621 <div class="modal-body">
622 <div class="ratio ratio-16x9">
623 <iframe class="w-100 h-100" src="@vinLookupServicePageUrl"></iframe>
624 </div>
625 </div>
626 </div>
627 </div>
628 </script>
629 }
630 @*END CUSTOM CODE*@
631
632 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
633
634 @{
635 string iconPath = "/Files/Icons/";
636 }
637
638 <button class="toggle-order-summary btn text-reset w-100 d-block d-lg-none px-0" type="button" data-bs-toggle="collapse" data-bs-target="#orderSummary" aria-expanded="false" aria-controls="orderSummary" id="OrderSummaryToggleButton">
639 <span class="d-flex align-items-center justify-content-between">
640 <span class="d-flex align-items-center gap-2">
641 <span class="fs-7 lh-1">
642 <span class="toggle-order-summary-text" id="OrderSummaryToggleButtonLabel">@Translate("Show order summary")</span>
643 </span>
644 <span class="icon-2" id="OrderSummaryToggleButtonIcon" style="transition: all 0.25s ease-in-out;">
645 @ReadFile(iconPath + "chevron-down.svg")
646 </span>
647 </span>
648 <span class="fw-bold">
649 <span class="text-price">@GetString("Ecom:Order.Price")</span>
650 </span>
651 </span>
652 </button>
653
654 <script>
655 const orderSummaryToggleButton = document.getElementById("OrderSummaryToggleButton");
656 const orderSummaryToggleButtonLabel = document.getElementById("OrderSummaryToggleButtonLabel");
657 const orderSummaryToggleButtonIcon = document.getElementById("OrderSummaryToggleButtonIcon");
658 const orderSummaryToggleText = '@Translate("Show order summary")';
659
660 orderSummaryToggleButton.addEventListener('click', function handleClick() {
661 if (orderSummaryToggleButtonLabel.textContent.toLowerCase().includes(orderSummaryToggleText.toLowerCase())) {
662 orderSummaryToggleButtonLabel.textContent = '@Translate("Hide order summary")';
663 orderSummaryToggleButtonIcon.classList.add("rotate-180");
664 } else {
665 orderSummaryToggleButtonLabel.textContent = orderSummaryToggleText;
666 orderSummaryToggleButtonIcon.classList.remove("rotate-180");
667 }
668 });
669 </script>
670
671
672 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
673
674 <div class="d-lg-block h-lg-auto collapse pt-2 pt-lg-0" id="orderSummary">
675 <div class="d-flex flex-column gap-2 gap-lg-3 pb-2 pb-lg-3">
676 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
677 @using Dynamicweb.Ecommerce.ProductCatalog
678
679 @functions {
680 private static string GetPrimaryImage(LoopItem orderline, string shopId)
681 {
682 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
683 bool isProduct = orderline.GetBoolean("Ecom:Order:OrderLine.IsProduct") || (orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount") && isProductIdOrNumber);
684 string productId = orderline.GetString("Ecom:Order:OrderLine.ProductID");
685 string variantId = orderline.GetString("Ecom:Order:OrderLine.ProductVariantID");
686
687 if (!isProduct || string.IsNullOrEmpty(productId)) return "";
688
689 ProductViewModelSettings productSetting = new ProductViewModelSettings
690 {
691 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID,
692 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code,
693 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2,
694 ShopId = shopId
695 };
696 ProductViewModel product = ViewModelFactory.CreateView(productSetting, productId, variantId);
697 return product.DefaultImage.Value;
698 }
699 }
700
701 @{
702 var orderlines = GetLoop("OrderLines");
703 }
704
705 @for (int i = orderlines.Count - 1; i >= 0; i--)
706 {
707 var orderline = orderlines[i];
708 string name = orderline.GetString("Ecom:Order:OrderLine.ProductName");
709 string orderlineImage = GetPrimaryImage(orderline, GetString("Ecom:Order.ShopID"));
710 string image = "/Admin/Public/GetImage.ashx?width=" + 180 + "&height=" + 180 + "&crop=5&fillcanvas=true&Background=ffffff&image=" + orderlineImage + "&format=webp";
711 image = !orderlineImage.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? orderlineImage : image;
712 string removeFromBasketLink = orderline.GetString("Ecom:Order:OrderLine.DeleteLink");
713 string priceTotalWithDiscounts = orderline.GetString("Ecom:Order:OrderLine.TotalPriceWithProductDiscounts.PriceFormatted");
714 string priceBefore = orderline.GetString("Ecom:Product.InformativePrice.PriceFormatted");
715 string unitPrice = orderline.GetString("Ecom:Order:OrderLine.UnitPrice.PriceFormatted");
716 string discountPrice = orderline.GetString("Ecom:Order:OrderLine.UnitPriceWithProductDiscount.PriceFormatted");
717 string discountTotal = orderline.GetString("Ecom:Order:OrderLine.TotalDiscount.PriceFormatted");
718 string variantText = orderline.GetString("Ecom:Order:OrderLine.ProductVariantText");
719 var orderlineId = orderline.GetValue("Ecom:Order:OrderLine.Id");
720 var quantity = orderline.GetDouble("Ecom:Order:OrderLine.Quantity");
721 var unitName = orderline.GetString("Ecom:Order:OrderLine.UnitName");
722 string primaryGroupId = orderline.GetString("Ecom:Order:OrderLine.PrimaryOrDefaultGroupId");
723 string productId = orderline.GetString("Ecom:Order:OrderLine.ProductID");
724 string variantId = orderline.GetString("Ecom:Order:OrderLine.ProductVariantID");
725 @*START CUSTOM CODE*@
726 var productNumber = orderline.GetString("Ecom:Order:OrderLine.ProductNumber");
727 @*END CUSTOM CODE*@
728
729 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop");
730 link += $"&GroupID={primaryGroupId}";
731 link += $"&ProductID={productId}";
732 link += !string.IsNullOrEmpty(variantId) ? $"&VariantID={variantId}" : "";
733
734 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
735 bool isProduct = orderline.GetBoolean("Ecom:Order:OrderLine.IsProduct") || (orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount") && isProductIdOrNumber);
736
737 if (isProduct)
738 {
739 <article class="grid grid-12">
740
741 <div class="g-col-2">
742 <a href="@link" class="ratio ratio-1x1 d-block " title="@name">
743 <img src="@image" style="object-fit: contain;" alt="@name">
744 </a>
745 </div>
746
747 <div class="g-col-10">
748
749 <div class="d-flex flex-column gap-1">
750 @* Title *@
751 <h3 class="h6 fs-7 m-0">
752 <a href="@link" class="text-decoration-none" title="@name">@name</a>
753 </h3>
754
755 @*START CUSTOM CODE - Show product number*@
756 @if (!string.IsNullOrEmpty(productNumber))
757 {
758 <p class="fs-8 fw-bold m-0">@productNumber</p>
759 }
760 @*END CUSTOM CODE*@
761
762 @* Variants *@
763 @if (!string.IsNullOrEmpty(variantText))
764 {
765 <p class="fs-8 m-0">@variantText</p>
766 }
767
768 @if (orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount"))
769 {
770 @* Free product notice *@
771 <p class="fs-8 m-0">@Translate("Free product")</p>
772 }
773 else
774 {
775 @* Unit price *@
776 <p class="fs-8 m-0">
777 @if (!string.IsNullOrEmpty(unitName))
778 {
779 <span>@unitName: </span>
780 }
781 @if (discountPrice == unitPrice)
782 {
783 <span class="text-price">@unitPrice</span>
784 }
785 else
786 {
787 <span class="text-price">@discountPrice</span>
788 <span class="text-decoration-line-through">
789 <span class="text-price">@unitPrice</span>
790 </span>
791 }
792 </p>
793 }
794 <div class="d-flex flex-row justify-content-between">
795 @* Quantity *@
796 <span class="fs-8 d-block">@Translate("Qty"): @quantity</span>
797
798 <div class="text-end flex-fill">
799 @* Total *@
800 <span class="h6 d-block fs-7 m-0">
801 <span class="text-price">@priceTotalWithDiscounts</span>
802 </span>
803 @if (orderline.GetDouble("Ecom:Order:OrderLine.TotalDiscount.Price.Value") != 0.0)
804 {
805 <span class="d-block fs-8">
806 <span class="text-price">@discountTotal</span>
807 </span>
808 }
809 </div>
810 </div>
811 </div>
812 </div>
813 </article>
814 }
815 }
816
817 </div>
818
819 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
820
821 @{
822 double totalPriceWithoutOrderDiscountsFeesAndTaxesValue = GetDouble("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.Price.Value") + GetDouble("Ecom:Order.TotalProductDiscount.Price.Value");
823 var orderCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(GetString("Ecom:Order.Currency.Code"));
824 string totalPriceWithoutOrderDiscountsFeesAndTaxes = Dynamicweb.Ecommerce.Services.Currencies.Format(orderCurrency, totalPriceWithoutOrderDiscountsFeesAndTaxesValue);
825
826 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower();
827 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat);
828
829 bool disableVouchers = Pageview.CurrentParagraph?.Item["DisableVouchers"] != null ? (Boolean)Pageview.CurrentParagraph.Item["DisableVouchers"] : false;
830 disableVouchers = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("CompletedOrderId")) ? true : disableVouchers;
831
832 <div class="d-flex flex-column gap-2 gap-lg-3 pb-3 bottom-0 sticky-receipt theme" id="orderSummaryFooter">
833
834 @if (!disableVouchers && Pageview.CurrentParagraph?.Item.SystemName != "Swift_QuoteCheckoutApp")
835 {
836 <text>
837 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
838 @using Dynamicweb.Ecommerce.Orders
839
840 @{
841 string voucherCode = GetString("Ecom:Order.Customer.VoucherCode");
842 string voucherCodeError = GetString("Ecom:Cart.ValidationError.EcomOrderVoucherCode.ErrorMessage");
843 string validState = string.Empty;
844 bool vouchersAppliedAsDiscounts = false;
845
846 IEnumerable<string> voucherCodes = new List<string>();
847 Order order = new OrderService().GetById(GetString("Ecom:Order.ID"));
848
849
850 if (!string.IsNullOrWhiteSpace(voucherCode))
851 {
852 if (order.VoucherUseType.HasFlag(VoucherUseCategoryType.Discount))
853 {
854 voucherCodes = voucherCode.Split(new string[] { ",", ";", " " }, StringSplitOptions.RemoveEmptyEntries);
855 vouchersAppliedAsDiscounts = true;
856 }
857 else
858 {
859 voucherCodes = new string[] { voucherCode.Trim() };
860 }
861 }
862
863 var voucherErrors = new List<string>();
864 if(!vouchersAppliedAsDiscounts)
865 {
866 foreach (string code in voucherCodes)
867 {
868 Dynamicweb.Ecommerce.Orders.Vouchers.Voucher vouch = Dynamicweb.Ecommerce.Services.Vouchers.GetVoucherByCode(code);
869 if (vouch == null)
870 {
871 validState = "is-invalid";
872 voucherErrors.Add(Translate("Voucher") + " <span class='fw-bold'>" + code + "</span> " + Translate("not found"));
873 continue;
874 }
875 if (vouch.DateUsed.HasValue)
876 {
877 validState = "is-invalid";
878 voucherErrors.Add(Translate("Voucher") + " <span class='fw-bold'>" + code + "</span> " + Translate("already used"));
879 continue;
880 }
881 }
882 }
883
884 var voucherErrorMessage = string.Join(",", voucherErrors);
885
886 <div class="py-3 border-top" id="orderVoucherForm">
887 <form method="post" id="VoucherForm">
888 <div class="input-group input-primary-button-group has-validation">
889 <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;">
890 <button class="btn btn-sm btn-primary d-inline-flex align-items-center justify-content-center" type="submit" id="EcomOrderVoucherApply" style="min-width: 100px;">
891 <span>@Translate("Apply")</span>
892 </button>
893
894 <div class="invalid-feedback">
895 @voucherErrorMessage
896 </div>
897 </div>
898 <input type="hidden" name="EcomOrderVoucherCode" id="EcomOrderVoucherCode" value="@voucherCode">
899 <label for="EcomOrderVoucherCodeField" class="visually-hidden">@Translate("Add voucher here")</label>
900 </form>
901
902 @if (!string.IsNullOrWhiteSpace(voucherCode) && vouchersAppliedAsDiscounts)
903 {
904 <div class="d-flex flex-wrap gap-2 pt-3">
905
906 @foreach (string code in voucherCodes)
907 {
908 <form method="post">
909 <input type="hidden" name="EcomOrderVoucherCode" value="@voucherCode.Replace(code+",", "").Replace(","+code, "").Replace(code, "")">
910 <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);">
911 <span class="icon-2">
912 @ReadFile("/Files/Templates/Designs/Swift/Assets/icons/tag.svg")
913 </span>
914 <span class="mx-2">@code</span>
915 <button type="submit" class="text-reset bg-transparent border-0 p-0" aria-label="@Translate("Remove voucher")" id="RemoveVoucherButton">
916 <span class="icon-2">
917 @ReadFile("/Files/Templates/Designs/Swift/Assets/icons/x.svg")
918 </span>
919 </button>
920 </span>
921 </form>
922 }
923 </div>
924 }
925 @voucherCodeError
926 </div>
927 }
928
929 </text>
930 }
931
932 <div class="fs-8 border-top pt-2 pt-lg-3">
933 @* Subtotal *@
934 <div class="d-flex justify-content-between fw-bold">
935 <span>@Translate("Subtotal")</span>
936 <span class="text-end">
937 <span class="d-block">
938 @if (GetDouble("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.Price.Value") != totalPriceWithoutOrderDiscountsFeesAndTaxesValue)
939 {
940 <span class="text-price fw-normal text-decoration-line-through">@GetString("Ecom:Order.TotalPriceWithoutDiscountsFeesAndTaxes.PriceFormatted")</span>
941 }
942 <span class="text-price">@totalPriceWithoutOrderDiscountsFeesAndTaxes</span>
943 </span>
944
945 @if (!neverShowVat && showPricesWithVat == "false")
946 {
947 <span class="fs-8 fw-normal d-block">@Translate("Excl. VAT")</span>
948 }
949 else if (!neverShowVat)
950 {
951 <span class="fs-8 fw-normal d-block">@Translate("Incl. VAT")</span>
952 }
953 </span>
954 </div>
955
956 @* Discounts (only order discounts) *@
957 @foreach (LoopItem orderline in GetLoop("OrderLines"))
958 {
959 bool isDiscount = orderline.GetBoolean("Ecom:Order:OrderLine.IsDiscount");
960 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
961 bool isOrderAmountDiscount = orderline.GetInteger("Ecom:Order:OrderLine.Type") == 1 && !isProductIdOrNumber;
962 if (isDiscount && isOrderAmountDiscount)
963 {
964 <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>
965 }
966 }
967
968 @* Delivery *@
969 @if (!string.IsNullOrEmpty(GetString("Ecom:Order.ShippingMethodID")))
970 {
971 if (GetDouble("Ecom:Order.ShippingFee.Price.Value") != 0.0)
972 {
973 <div class="d-flex justify-content-between">
974 <span>@Translate("Delivery")</span>
975 <span>@GetString("Ecom:Order.ShippingFee.PriceFormatted")</span>
976 </div>
977 }
978 }
979 else
980 {
981 <div class="d-flex justify-content-between">
982 <span>@Translate("Delivery")</span>
983 <span>@Translate("Calculated in next step")</span>
984 </div>
985 }
986
987 @* Payment *@
988 @if (!string.IsNullOrEmpty(GetString("Ecom:Order.PaymentMethodID")))
989 {
990 if (GetDouble("Ecom:Order.PaymentFee.Price.Value") != 0)
991 {
992 <div class="d-flex justify-content-between">
993 <span>@Translate("Payment")</span>
994 <span class="text-price">@GetString("Ecom:Order.PaymentFee.PriceFormatted")</span>
995 </div>
996 }
997 }
998 else
999 {
1000 <div class="d-flex justify-content-between">
1001 <span>@Translate("Payment")</span>
1002 <span>@Translate("Calculated in next step")</span>
1003 </div>
1004 }
1005
1006 @* Taxes *@
1007 @if (GetDouble("Ecom:Order.Taxes.Total.Price.Value") != 0)
1008 {
1009 <div class="d-flex justify-content-between mb-2">
1010 <span>@Translate("Sales tax")</span>
1011 <span>@GetString("Ecom:Order.Taxes.Total.PriceFormatted")</span>
1012 </div>
1013 }
1014 </div>
1015 <div class="fs-8 border-top pt-2 pt-lg-3">
1016 <div class="d-flex justify-content-between fs-6 fw-bold">
1017 <span>@Translate("Total")</span>
1018 @if (!neverShowVat && showPricesWithVat == "false")
1019 {
1020 <span class="text-price text-end">
1021 <span class="fs-5 d-block">@GetString("Ecom:Order.Price.PriceFormatted")</span>
1022 <span class="fs-8 fw-normal d-block">@Translate("Excl. VAT")</span>
1023 </span>
1024 }
1025 else if (!neverShowVat && showPricesWithVat == "true")
1026 {
1027 <span class="text-price text-end">
1028 <span class="fs-5 d-block">@GetString("Ecom:Order.Price.PriceFormatted")</span>
1029 <span class="fs-8 fw-normal d-block">@Translate("Incl. VAT")</span>
1030 </span>
1031 }
1032 else
1033 {
1034 <span class="text-price fs-5">@GetString("Ecom:Order.Price.PriceFormatted")</span>
1035 }
1036 </div>
1037
1038 @if (!neverShowVat)
1039 {
1040 <div class="d-flex justify-content-between"><span>@Translate("VAT")</span><span class="text-price">@GetString("Ecom:Order.Price.VATFormatted")</span></div>
1041 if (showPricesWithVat == "false")
1042 {
1043 <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>
1044 }
1045 }
1046
1047 @if (GetDouble("Ecom:Order.TotalDiscount.Price.Value") != 0)
1048 {
1049 <div class="d-flex justify-content-between"><span>@Translate("Discount")</span><span class="text-price">@GetString("Ecom:Order.TotalDiscount.PriceFormatted")</span></div>
1050 }
1051 </div>
1052 </div>
1053 }
1054
1055 </div>
1056
1057 </div>
1058 }
1059
1060
1061 </div>
1062
1063 <script>
1064 function submitForm() {
1065 document.querySelector("#CurrentStep").name = "@GetString("CartV2.CurrentStepButtonName")";
1066 swift.PageUpdater.Update(document.querySelector("#ordersubmit"));
1067 }
1068 </script>
1069