Error executing template "Designs/identity_v2/eCom7/CartV2/Step/espresso-cart.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_c3b5d6ef1d1c45b38409efb0d2f6477d.Execute() in D:\dynamicweb.net\Solutions\id.espresso4.dk-e5\Application\Files\Templates\Designs\identity_v2\eCom7\CartV2\Step\espresso-cart.cshtml:line 465
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 RazorTemplateBase< RazorTemplateModel< Template > >
2 @using System
3 @using System.Collections.Generic
4 @using System.Linq
5 @using System.Web.Mvc
6 @using Co3.Espresso.Base.Extensions
7 @using Co3.Espresso.Website.Services
8 @using Co3.ID.Dw.Helpers
9 @using Co3.ID.Dw.Models.Frontend.Users
10 @using Dynamicweb.Ecommerce.Common
11 @using Dynamicweb.Ecommerce.Orders
12 @using Dynamicweb.Ecommerce.Orders.SalesDiscounts
13 @using Dynamicweb.Environment.Web
14 @using Dynamicweb.Frontend
15 @using Dynamicweb.Rendering
16 @using Dynamicweb.Security.UserManagement
17 @using Co3.Espresso.Website.Models.FrontEnd.Settings
18 @using Order = Dynamicweb.Ecommerce.Orders.Order
19 @using OrderLine = Dynamicweb.Ecommerce.Orders.OrderLine
20 @using ProductService = Co3.Espresso.Website.Services.ProductService
21 @using Dynamicweb.Ecommerce.Common;
22 @using Co3.ID.Dw.Models.Frontend.Ecommerce
23 @using Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Extensions
24
25
26 @{
27 string globalAreaName = PageView.Current().Area.UrlName;
28 bool globalPrefix = PageView.Current().Area.UrlIgnoreForChildren;
29 if (globalPrefix == true)
30 {
31 globalAreaName = string.Empty;
32 }
33
34 Order order = null;
35
36 // TODO: We are having an issue with that DW is not recalculating the basket, fast or good enough...
37 if (Dynamicweb.Context.Current.Request.HttpMethod == "POST")
38 {
39 order = Context.Cart;
40 Dynamicweb.Ecommerce.Services.Orders.ForcePriceRecalculation(order);
41 }
42 bool isCustomerShop = (PageView.Current().Area.Item["IsCustomerShop"] != null && (bool)PageView.Current().Area.Item["IsCustomerShop"] == true);
43 bool showPrices = !isCustomerShop || (isCustomerShop && UserContext.Current.CustomerShop.Settings.ShowPrices == true);
44
45
46 if (Context.Cart != null)
47 {
48 order = Context.Cart;
49 }
50
51 int orderlineCount = 1;
52 }
53
54 <div class="row">
55 <div class="col-12 col-xl-10 mx-xl-auto">
56
57 <div class="e-cart js-e-cart js-e-require" data-require="cart">
58 <div class="no-gutters row">
59 <div class="col-12 col-md-5 col-lg-4 mb-2 mb-md-0 order-md-last pl-md-3">
60
61 <div class="e-cart-aside js-e-cart-aside js-e-loading-wait bg-light py-2 py-lg-3 px-2 ">
62 <div class="small">
63
64 <div class="js-e-order-summary @(!SiteContext.ShowPrices() ? "d-none" : string.Empty)">
65 <script id="js-e-handlebars-tmpl-order-summary" type="text/x-handlebars-template">
66 <div class="row pt-0 mb-1 d-none d-lg-flex">
67 <div class="col-4">
68 <p class="mb-0 text-black">@Translate( "eCom Checkout - Subtotal - Text", "Subtotal" )</p>
69 </div>
70 <div class="col-8">
71 <p class="mb-0 text-right text-black">{{{cart.priceWithoutDiscountsFeesAndTaxes}}}</p>
72 </div>
73 </div>
74 <div class="row mb-1 d-none d-lg-flex">
75 <div class="col-6">
76 <p class="mb-0 text-black">@Translate( "eCom Checkout - Shipping - Text", "Shipping" )<br><span class="text-muted">({{cart.shippingmethod.name}})</span></p>
77 </div>
78 <div class="col-6">
79 <p class="mb-0 text-right text-black">{{{cart.shippingmethod.price}}}</p>
80 </div>
81 </div>
82 {{#if cart.discountPrice}}
83 <div class="row mb-1 d-none d-lg-flex">
84 <div class="col-6">
85 <p class="mb-0 text-black">@Translate( "eCom Checkout - Discount - Text", "Rabat" )</p>
86 </div>
87 <div class="col-6">
88 <p class="mb-0 text-right text-black">{{{cart.discountPrice}}}</p>
89 </div>
90 </div>
91 {{/if}}
92
93 {{#if cart.voucherMessages}}
94 <div class="row mb-1 d-none d-lg-flex">
95 <div class="col-12 text-danger">
96 {{#each cart.voucherMessages as |error|}}
97 <i class="material-icons">info</i> {{{error}}}
98 {{/each}}
99 </div>
100 </div>
101 {{/if}}
102
103 <hr class="border-black d-none d-lg-block">
104 <div class="row mb-1">
105 <div class="col-4">
106 <p class="h3 mb-0"> @Translate( "eCom Checkout - Total - Text", "Total" ) </p>
107 </div>
108 <div class="col-8">
109 <p class="h3 mb-0 text-right">{{{cart.price}}}</p>
110 </div>
111 </div>
112 <div class="row mb-1">
113 <div class="col-5">
114 <p class="mb-0 small font-weight-semibold"> @Translate( "eCom Checkout - Vat - Text", "Vat" ) </p>
115 </div>
116 <div class="col-7">
117 <p class="mb-0 text-right text-black">{{{cart.priceVAT}}}</p>
118 </div>
119 </div>
120 </script>
121 </div>
122
123 @inherits RazorTemplateBase< RazorTemplateModel< Template > >
124 @using System
125 @using System.Collections.Generic
126 @using System.Linq
127 @using Co3.Espresso.Website.Services
128 @using Co3.ID.Dw.Helpers
129 @using Dynamicweb.Ecommerce.Orders
130 @using Dynamicweb.Ecommerce.Orders.SalesDiscounts
131 @using Dynamicweb.Frontend
132 @using Dynamicweb.Rendering
133 @using Dynamicweb.Security.UserManagement
134
135 @inherits RazorTemplateBase< RazorTemplateModel< Template > >
136 @using System
137 @using System.Collections.Generic
138 @using System.Linq
139 @using Co3.Espresso.Website.Services
140 @using Co3.ID.Dw.Helpers
141 @using dwOrderService = Dynamicweb.Ecommerce.Orders
142 @using Dynamicweb.Ecommerce.Orders.SalesDiscounts
143 @using Dynamicweb.Frontend
144 @using Dynamicweb.Rendering
145 @using Dynamicweb.Security.UserManagement
146
147 @functions
148 {
149 List<string> GetVoucherMessages()
150 {
151 List<string> returnValue = new List<string>();
152
153 string voucherCode = GetString("Ecom:Order.Customer.VoucherCode");
154
155 if (!string.IsNullOrWhiteSpace(voucherCode))
156 {
157 dwOrderService.Order orderById = dwOrderService.Order.GetOrderById(GetString("Ecom:Order.ID"));
158
159 IEnumerable<string> codes = new List<string>();
160 bool vouchersAppliedAsDiscounts = false;
161
162 if (orderById.VoucherUseType.HasFlag(dwOrderService.VoucherUseCategoryType.Discount))
163 {
164 codes = voucherCode.Split(new string[] {",", ";", " "}, StringSplitOptions.RemoveEmptyEntries);
165 vouchersAppliedAsDiscounts = true;
166 }
167 else
168 {
169 codes = new string[] {voucherCode.Trim()};
170 }
171
172 if (vouchersAppliedAsDiscounts && codes.Count() == 1)
173 {
174 }
175 else
176 {
177 foreach (string code in codes)
178 {
179 Voucher vouch = Voucher.GetVoucherByCode(code);
180 if (vouch == null)
181 {
182 returnValue.Add(Translate("Voucher") + " <span class=font-weight-bold>" + code + "</span> " + Translate("not found"));
183 continue;
184 }
185 if (vouch.DateUsed.HasValue)
186 {
187 returnValue.Add(Translate("Voucher") + " <span class=font-weight-bold>" + code + "</span> " + Translate("already used"));
188 continue;
189 }
190
191 VoucherList voucherList = VoucherList.GetListById(vouch.ListId);
192 if (!voucherList.ListActive)
193 {
194 returnValue.Add(Translate("Voucher") + " <span class=font-weight-bold>" + code + "</span> " + Translate("is not active"));
195 continue;
196 }
197
198 }
199 }
200 }
201 return returnValue;
202 }
203 }
204
205
206 @{
207 ShopType shopContext = SiteContext.CurrentSiteContext();
208 bool isImpersonating = PageView.Current().User != null && PageView.Current().User.CurrentSecondaryUser != null;
209 List<string> voucherMessages = GetVoucherMessages();
210 }
211
212
213
214 @if ((shopContext == ShopType.B2C || (shopContext == ShopType.B2B && isImpersonating)) && string.IsNullOrEmpty(GetString("Ecom:Order.Completed")))
215 {
216 <form class="e-cart-voucher-form js-e-cart-voucher-form small" method="post">
217 <label class="form-control-label mr-1 d-none d-md-block" for="EcomOrderVoucherCode">
218 @Translate("eCom Cart - Voucher - Label", "Voucher code")
219 </label>
220 <div class="align-items-center row no-gutters">
221 <label class="form-control-label mr-1 d-block d-sm-none" for="EcomOrderVoucherCode">
222 @Translate("eCom Cart - Voucher - Label", "Voucher code")
223 </label>
224 <div class="col flex-grow-1">
225 <input class="form-control js-e-checkout-company" id="EcomOrderVoucherCode" name="EcomOrderVoucherCode" type="text" value="@GetString("Ecom:Order.Customer.VoucherCode")" placeholder="@Translate("eCom Cart - Voucher - Placeholder", "Voucher code")">
226 </div>
227 <div class="col flex-grow-0 pl-1">
228 <button class="btn btn-secondary btn-sm js-e-cart-update-btn" type="submit">@Translate("eCom Cart - Voucher apply - Button", "Apply")</button>
229 </div>
230 </div>
231
232
233 @foreach (string voucherMessage in voucherMessages)
234 {
235 <p class="small mt-1 text-danger"><i class="material-icons">error</i> @voucherMessage</p>
236 }
237 </form>
238 }
239
240 <div class="mb-0 mt-2 row">
241 <div class="col-12">
242 <a class="arrow-right btn btn-block btn-lg btn-success px-0 py-1 js-e-checkout-btn" href="@globalAreaName/shop/cart/checkout">@Translate( "eCom Checkout - Checkout - Button", "Checkout" )</a>
243 </div>
244 </div>
245
246 <div class="e-loading-overlay js-e-loading-overlay">
247 @RenderingService.Instance.PartialView( "_partials/loading-spinner.cshtml" )
248 </div>
249 </div>
250 </div>
251
252 </div>
253 <div class="col-12 col-md-7 col-lg-8">
254
255 <div class="e-cart-main js-e-cart-main js-e-loading-wait">
256 <div class="small">
257 <div class="d-flex justify-content-between align-items-center">
258 <h4 class="m-0 mb-2 d-flex align-items-center">
259 @ImageService.Instance.GetSvgMarkup("/Files/Images/icons/outline/41-shopping/shopping-cart-4.svg")
260 <span class="js-e-cart-quantity"></span> @Translate("eCom Cart - Heading", "Items in your basket")
261 </h4>
262 <span class="small">
263 <a href="#" class="btn btn-sm btn-primary js-identity-clear-cart">@Translate("DownloadManager - Cart - RemoveAll", "Remove all")</a>
264 </span>
265 </div>
266
267 <div class="alert alert-danger js-identity-cart-stock-alert d-none">
268 <p class="m-0 text-center">@Translate("eCom - Cart - Stock Alert", "Der er produkter i din kurv, som vi desværre ikke har på lager")</p>
269 </div>
270
271
272 <form action="" class="e-cart-form js-e-cart-form" method="post">
273 <input class="js-e-cart-form-cartcmd" name="CartCmd" type="hidden" value="updateorderlines">
274 <input class="js-e-cart-form-redirect" name="Redirect" type="hidden" value="false">
275 <div class="js-e-cart-orderlines">
276 @using Co3.ID.Dw.Helpers
277
278 <script id="js-e-handlebars-tmpl-cart-orderlines" type="text/x-handlebars-template">
279 {{#unless cart.orderlines}}
280 <p class="my-2">@Translate( "eCom Checkout - Empty Cart - Text", "Your cart is empty, but it doesn’t have to be." )</p>
281 {{/unless}}
282 {{#each cart.orderlines}}
283
284 {{#unless customerShopRelatedProductId}}
285 <div class="e-orderline js-e-orderline pt-2 pb-1 {{#if overStock}}has-over-stock{{/if}}" id="{{id}}" data-product-id="{{product.id}}" data-product-name="{{product.name}}" data-product-number="{{product.number}}" data-product-price="{{unitPriceClean}}" data-product-quantity="{{quantity}}" data-product-variant-id="{{product.variantId}}" data-color-variant-text="{{product.colorVariantText}}" data-brand-code="{{product.brandCode}}" data-brand-name="{{product.brandName}}">
286 <div class="row">
287
288 <div class="col-3 col-lg-2">
289 <p class="e-orderline-product-image">
290 <a href="{{product.link}}" tabindex="-1">
291 <img alt="" class="img-fluid" src="{{{product.imagePrimary.small}}}">
292 </a>
293 </p>
294 </div>
295
296 <div class="col-9 col-lg-10">
297 <div class="no-gutters row align-items-top">
298
299 <div class="col-12">
300 <p class="e-product-brand d-block mb-0 font-weight-bold text-black small">{{product.brandNameText}}</p>
301 </div>
302
303 <div class="col-8 col-md-8">
304 <p class="e-product-name mt-0 mb-1 ">
305 <a href="{{product.link}}" tabindex="-1">
306 {{product.number}} {{product.name}}
307 </a>
308 {{#hasRelatedProductOrderline @@root.cart.orderlines product.id}}
309 <span class="badge badge-dark ml-1">@Translate( "eCom Checkout - Orderline has related product - Text", "Transfer" )</span>
310 {{#each @@root.cart.orderlines as |relatedProductOrderLine|}}
311 {{#if relatedProductOrderLine.customerShopRelatedProductId}}
312 {{#compare relatedProductOrderLine.customerShopRelatedProductId '===' ../product.id}}
313 <input class="js-identity-orderline-related-id" type="hidden" value="{{relatedProductOrderLine.id}}" data-product-id="{{../product.id}}" />
314 {{/compare}}
315 {{/if}}
316 {{/each}}
317
318 {{/hasRelatedProductOrderline}}
319 </p>
320 {{#if overStock}}
321 <p class="mt-0 mb-1 text-danger small">
322 @Translate("eCom - Orderline - Stock Alert - Text 1", "Bestilling må ikke overstige lagerbeholdningen") ({{product.stockQuantity}})<br />
323 @Translate("eCom - Orderline - Stock Alert - Text 2", "Ændre venligst antallet for at gennemføre din bestilling")
324 </p>
325 {{/if}}
326
327 <p class="e-product-variant d-block mb-0">
328 @Translate( "eCom Checkout - Orderline color variant - Text", "Farve" ): {{product.colorVariantText}}
329 </p>
330 <p class="e-product-variant d-block mb-1">
331 @Translate( "eCom Checkout - Orderline size variant - Text", "Størrelse" ): {{product.sizeVariantText}}
332 </p>
333
334 </div>
335
336 <div class="col-4 col-md-4">
337 @if (SiteContext.ShowPrices())
338 {
339 <p class="e-orderline-product-price mb-0 text-right">
340 {{{unitPrice}}}
341 </p>
342 }
343
344
345 <div class="no-gutters row d-flex justify-content-end">
346 <div class="col-6 col-md-4 mt-2 d-flex justify-content-end">
347 <input class="form-control js-e-orderline-quantity-input e-orderline-quantity-input text-center" data-rule-digits="true" data-rule-min="0" max="{{product.stockQuantity}}" name="QuantityOrderLine{{id}}" type="text" value="{{quantity}}">
348 <button class="btn btn-sm btn-tertiary js-e-orderline-update-btn d-none" tabindex="-1">@Translate( "eCom Checkout - Update orderline - Button", "Update" )</button>
349 </div>
350 </div>
351
352 </div>
353 {{#if showOrderLineComment}}
354
355 <div class="col-12">
356 <div class="form-group">
357 <input type="text" class="form-control js-e-orderline-comment-input" name="{{comment.inputFieldName}}" value="{{comment.value}}" placeholder="@(Translate("eCom Checkout - Orderline comment - Text", "Her indtastes dit navn, Rekv. nr. eller ligende"))" maxlength="255">
358 </div>
359 </div>
360
361
362 {{/if}}
363
364
365 <div class="col-12 col-md-12 order-md-2">
366 <p class="mb-1 small text-left">
367 <a class="btn btn-sm btn-tertiary js-e-orderline-delete-btn" href="{{product.link}}" tabindex="-1">
368 <i class="material-icons">close</i>
369 <small>@Translate( "eCom Checkout - Delete orderline - Button", "Remove" )</small>
370 </a>
371 </p>
372 </div>
373 </div>
374 </div>
375 </div>
376 </div>
377 {{/unless}}
378
379 {{/each}}
380
381
382 {{#each cart.discountOrderlines}}
383 {{#if isDiscount}}
384
385 {{#compare product.number '===' 'FEE'}}
386
387 {{#if priceClean}}
388 <div class="col-12">
389 <div class="alert alert-success m-0 d-flex justify-space-between">
390 <strong>{{product.name}}</strong>
391 <strong class="small">
392 {{{price}}}
393 </strong>
394 </div>
395 </div>
396 {{/if}}
397
398 {{else}}
399 {{#compare shopContext '===' 'B2C'}}
400 {{#compare name '!==' 'Dibs'}}
401 <div class="col-xs-12">
402 <div class="alert alert-success m-0 d-flex justify-space-between">
403 <strong>{{discount.description}}</strong>
404 <strong class="small">
405 {{{price}}}
406 </strong>
407 </div>
408 </div>
409 {{else}}
410 {{/compare}}
411 {{/compare}}
412
413 {{#compare shopContext '===' 'B2B'}}
414 {{#if @@root.cart.showPrices}}
415 <div class="col-12 mb-1">
416 <div class="alert alert-success m-0 d-flex justify-content-between">
417 <strong>{{name}}</strong>
418 <strong class="small">
419 {{{price}}}
420 </strong>
421 </div>
422 </div>
423 {{/if}}
424 {{/compare}}
425
426 {{/compare}}
427
428
429 {{/if}}
430 {{/each}}
431 </script>
432
433 </div>
434
435
436 </form>
437
438 <div class="e-loading-overlay js-e-loading-overlay">
439 @RenderingService.Instance.PartialView("_partials/loading-spinner.cshtml")
440 </div>
441 </div>
442
443 @*<div class="row">
444 <div class="col-6">
445 </div>
446 <div class="col-6 text-right">
447 <a class="arrow-right btn btn-success" href="@globalAreaName/shop/cart/checkout">@Translate( "eCom Checkout - Checkout - Button", "Checkout" )</a>
448 </div>
449 </div>*@
450
451 </div>
452
453 </div>
454 </div>
455 </div>
456
457 </div>
458 </div>
459 <script>
460 /* NEW GA4 */
461 dataLayer.push({
462 event : "view_cart",
463 ecommerce: {
464 items: [
465 @foreach (OrderLine orderLine in order.OrderLines)
466 {
467 IdentityProduct orderlineEspressoProduct = null;
468 bool isDiscount = orderLine.IsDiscount();
469
470 if (isDiscount == false)
471 {
472 orderlineEspressoProduct = (IdentityProduct) ProductService.Instance.GetEspressoProduct(
473 new ProductSettings()
474 {
475 Id = orderLine.ProductId,
476 VariantId = orderLine.ProductVariantId,
477 PrimaryVariantId = orderLine.ProductVariantId,
478 EmbeddedInModelList = true
479 }
480 );
481
482 if (orderlineCount > 1)
483 {
484 @Raw(",")
485 }
486
487 <text>
488 {
489 item_id: "@orderlineEspressoProduct.Number",
490 item_name: "@orderlineEspressoProduct.Name",
491 price: @orderlineEspressoProduct.Price.Value.ToJavaScript().Replace(",", ""),
492 quantity: @orderLine.Quantity
493 }
494 </text>
495
496 orderlineCount++;
497 }
498 }
499 ]
500 }
501 });
502 </script>