forked from VirtoCommerce/vc-platform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CartController.cs
481 lines (412 loc) · 17.4 KB
/
CartController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using VirtoCommerce.Client;
using VirtoCommerce.Foundation.Catalogs.Model;
using VirtoCommerce.Foundation.Orders.Model;
using VirtoCommerce.Web.Client.Extensions;
using VirtoCommerce.Client.Globalization;
using VirtoCommerce.Web.Client.Helpers;
using VirtoCommerce.Web.Models;
using VirtoCommerce.Web.Virto.Helpers;
namespace VirtoCommerce.Web.Controllers
{
/// <summary>
/// Class CartController.
/// </summary>
public class CartController : ControllerBase
{
#region Private Fields
// contains list of carts
/// <summary>
/// The _carts
/// </summary>
private readonly Dictionary<string, CartHelper> _carts = new Dictionary<string, CartHelper>();
/// <summary>
/// The _catalog client
/// </summary>
private readonly CatalogClient _catalogClient;
/// <summary>
/// The _country client
/// </summary>
private readonly CountryClient _countryClient;
#endregion
#region Constructors
/// <summary>
/// Cart controller constructor
/// </summary>
/// <param name="catalogClient">Catalog client used to access catalog repository methods through caching and other helpers</param>
/// <param name="countryClient">Allows to get countries from repository through caching</param>
public CartController(CatalogClient catalogClient, CountryClient countryClient)
{
_catalogClient = catalogClient;
_countryClient = countryClient;
}
#endregion
/// <summary>
/// Cart home page
/// </summary>
/// <returns>ActionResult.</returns>
public ActionResult Index()
{
var helper = GetCartHelper(CartHelper.CartName);
if (!helper.IsEmpty)
{
helper.SaveChanges();
}
if (helper.IsEmpty)
{
return View("Empty");
}
var model = CreateCartModel(helper);
return View("Index", model);
}
/// <summary>
/// Configures the specified line item by given identifier.
/// </summary>
/// <param name="lineItemId">The line item identifier.</param>
/// <returns>ActionResult.</returns>
public ActionResult Configure(string lineItemId)
{
var cart = GetCartHelper(CartHelper.CartName);
var lineItem = cart.LineItems.FirstOrDefault(li => li.LineItemId == lineItemId);
if (lineItem == null)
{
cart = GetCartHelper(CartHelper.WishListName);
lineItem = cart.LineItems.FirstOrDefault(li => li.LineItemId == lineItemId);
}
if (lineItem != null)
{
Response.Redirect(Url.ItemUrl(lineItem.CatalogItemId, lineItem.ParentCatalogItemId));
}
return RedirectToAction("Index");
}
/// <summary>
/// Removes the specified line item.
/// </summary>
/// <param name="lineItemId">The line item identifier.</param>
/// <param name="sourceView">The source view.</param>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult Remove(string lineItemId, string sourceView = "LineItems")
{
return RemoveFrom(lineItemId, CartHelper.CartName, false, sourceView);
}
/// <summary>
/// Removes from wish list.
/// </summary>
/// <param name="lineItemId">The line item identifier.</param>
/// <param name="sourceView"></param>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult RemoveFromWishList(string lineItemId, string sourceView = "WishList")
{
return RemoveFrom(lineItemId, CartHelper.WishListName, false, sourceView, false);
}
/// <summary>
/// Removes from compare list.
/// </summary>
/// <param name="lineItemId">The line item identifier.</param>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult RemoveFromCompareList(string lineItemId)
{
return RemoveFrom(lineItemId, CartHelper.CompareListName, false, "MiniCompareList");
}
/// <summary>
/// Updates the specified line items.
/// </summary>
/// <param name="lineItems">The line items.</param>
/// <param name="cartbutton">The cartbutton.</param>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult Update(List<LineItemUpdateModel> lineItems, string cartbutton)
{
var cart = GetCartHelper(CartHelper.CartName);
var hasUpdates = false;
if (cartbutton == "clear")
{
cart.Delete();
hasUpdates = true;
}
else
{
foreach (var ml in lineItems)
{
var ml1 = ml;
foreach (var li in cart.LineItems.Where(li => li.LineItemId == ml1.LineItemId).ToArray())
{
if (ml.Quantity <= 0)
{
cart.Remove(li);
}
else
{
li.Quantity = ml.Quantity;
}
hasUpdates = true;
}
}
}
if (hasUpdates)
{
SaveChanges(cart);
}
return RedirectToAction("Index");
}
/// <summary>
/// Removes line item from specified cart.
/// </summary>
/// <param name="lineItemId">The line item identifier.</param>
/// <param name="cartName">Name of the cart.</param>
/// <param name="clear">if set to <c>true</c> [clear] all cart.</param>
/// <param name="sourceView">The source view. View that initiated remove action.</param>
/// <param name="renderView">True if partial view should be rendered</param>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult RemoveFrom(string lineItemId, string cartName, bool clear = false, string sourceView = "LineItems", bool renderView = true)
{
var helper = GetCartHelper(cartName);
var name = String.Empty;
if (!helper.IsEmpty)
{
foreach (var item in helper.LineItems.Where(item => item.LineItemId == lineItemId || clear).ToArray())
{
name = item.DisplayName;
helper.Remove(item);
}
}
// If cart is empty, remove it from the database
if (helper.IsEmpty)
{
helper.Delete();
}
SaveChanges(helper);
// Display the confirmation message
var results = new CartRemoveModel
{
CartSubTotal = StoreHelper.FormatCurrency(helper.Cart.Subtotal, helper.Cart.BillingCurrency),
CartTotal = StoreHelper.FormatCurrency(helper.Cart.Total, helper.Cart.BillingCurrency),
CartCount = helper.LineItems.Count(),
LineItemsView = renderView && !string.IsNullOrEmpty(sourceView) ? RenderRazorViewToString(sourceView, cartName == CartHelper.CompareListName ?
(object)helper.CreateCompareModel() : helper.CreateCartModel(true)) : "",
Source = sourceView,
DeleteId = lineItemId,
CartName = cartName
};
results.Messages.Add(new MessageModel(string.Format("{0} have been removed from your {1}.".Localize(), clear ? "Items " : Server.HtmlEncode(name), cartName)));
return Json(results);
}
/// <summary>
/// Adds line item to the specified cart by name.
/// Additionally adds related items if any are specified
/// </summary>
/// <param name="name">The name.</param>
/// <param name="itemId">The item identifier.</param>
/// <param name="parentItemId">The parent item identifier.</param>
/// <param name="quantity">The quantity to add.</param>
/// <param name="relatedItemId">The related items identifier.</param>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult Add(string name, string itemId, string parentItemId, decimal? quantity, string[] relatedItemId = null)
{
decimal qty = 1;
if (quantity.HasValue)
{
qty = quantity.Value;
}
if (String.IsNullOrEmpty(name))
{
name = CartHelper.CartName;
}
var helper = GetCartHelper(name);
var catalogItem = _catalogClient.GetItem(itemId);
var parentItem = !string.IsNullOrEmpty(parentItemId) ? _catalogClient.GetItem(parentItemId) : null;
var addedLineItems = new List<LineItemModel>();
var addedLineItem = DoAddToCart(name, qty, catalogItem, parentItem);
if (addedLineItem != null)
{
addedLineItems.Add(new LineItemModel(addedLineItem, catalogItem, parentItem, helper.Cart.BillingCurrency));
}
if (relatedItemId != null && relatedItemId.Length > 0)
{
addedLineItems.AddRange(from relItemId in relatedItemId
let relItem = _catalogClient.GetItem(relItemId)
let relatedItem = DoAddToCart(name, 1, relItem, null)
where relatedItem != null
select new LineItemModel(relatedItem, relItem, null, helper.Cart.BillingCurrency));
}
if (Request.UrlReferrer != null)
{
UserHelper.CustomerSession.LastShoppingPage = Request.UrlReferrer.AbsoluteUri;
}
//helper.ClearCache();
//helper = GetCartHelper(name);
var results = new CartJsonModel
{
CartSubTotal = StoreHelper.FormatCurrency(helper.Cart.Subtotal, helper.Cart.BillingCurrency),
CartTotal = StoreHelper.FormatCurrency(helper.Cart.Total, helper.Cart.BillingCurrency),
CartCount = helper.LineItems.Count(),
LineItemsView = null,
CartName = name
};
results.Messages.Add(new MessageModel(string.Format("{0} items added to your {1}".Localize(), addedLineItems.Sum(li =>li.Quantity), name.Localize())));
return Json(results);
}
/// <summary>
/// Mini cart view
/// </summary>
/// <returns>Mini cart view</returns>
public ActionResult MiniView()
{
var ch = GetCartHelper(CartHelper.CartName);
return PartialView("MiniCart", CreateCartModel(ch));
}
/// <summary>
/// Renders add to cart button
/// </summary>
/// <param name="itemId">The item identifier.</param>
/// <param name="parentItemId">The parent item identifier.</param>
/// <param name="forcedActive">if set to <c>true</c> item is added regardless if its active.</param>
/// <returns>ActionResult.</returns>
public ActionResult AddToCart(string itemId, string parentItemId, bool forcedActive = true)
{
return PartialView(CatalogHelper.CreateCatalogModel(itemId, parentItemId, forcedActive: forcedActive));
}
/// <summary>
/// Applies the discount coupon.
/// </summary>
/// <param name="couponCode">The coupon code.</param>
/// <param name="renderItems">if set to <c>true</c> render items and returns with json.</param>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult ApplyCoupon(string couponCode, bool renderItems = false)
{
_catalogClient.CustomerSession.CouponCode = couponCode;
var helper = GetCartHelper(CartHelper.CartName);
var warnings = SaveChanges(helper);
// Display the confirmation message
var results = new CartJsonModel
{
CartSubTotal = StoreHelper.FormatCurrency(helper.Cart.Subtotal, helper.Cart.BillingCurrency),
CartTotal = StoreHelper.FormatCurrency(helper.Cart.Total, helper.Cart.BillingCurrency),
CartCount = helper.LineItems.Count(),
LineItemsView = renderItems ? RenderRazorViewToString("LineItems", helper.CreateCartModel(true)) : null,
CartName = CartHelper.CartName,
Source = "LineItems"
};
if (warnings != null)
{
foreach (var warning in warnings.Values)
{
results.Messages.Add(new MessageModel(warning));
}
}
if (warnings == null || !warnings.ContainsKey(WorkflowMessageCodes.COUPON_NOT_APPLIED))
{
results.Messages.Add(string.IsNullOrEmpty(couponCode)
? new MessageModel("Coupon has been cleared".Localize())
: new MessageModel("Coupon has been applied".Localize()));
}
return Json(results);
}
/// <summary>
/// Clears the compare list.
/// </summary>
/// <returns>ActionResult.</returns>
[HttpPost]
public ActionResult ClearCompareList()
{
return RemoveFrom(null, CartHelper.CompareListName, true, "MiniCompareList");
}
/// <summary>
/// Saves the cart changes.
/// </summary>
/// <param name="helper">The helper.</param>
/// <returns>Dictionary of errors if any.</returns>
private Dictionary<string, string> SaveChanges(CartHelper helper)
{
if (helper.Cart.Name != CartHelper.CartName)
{
_catalogClient.CustomerSession["SkipRewards"] = true;
}
var errors = new Dictionary<string, string>();
if (helper.Cart.Name == CartHelper.CartName)
{
var result = helper.RunWorkflow("ShoppingCartValidateWorkflow");
if (result.WorkflowResult.Warnings != null)
{
foreach (var warning in result.WorkflowResult.Warnings.Distinct())
{
errors.Add(warning.Code, warning.Parameters["Message"]);
}
}
}
helper.SaveChanges();
return errors;
}
/// <summary>
/// Gets the cart helper.
/// </summary>
/// <param name="name">The cart name.</param>
/// <returns>CartHelper.</returns>
private CartHelper GetCartHelper(string name)
{
if (!_carts.ContainsKey(name))
{
_carts.Add(name, new CartHelper(name));
}
return _carts[name];
}
/// <summary>
/// Creates the cart model.
/// </summary>
/// <param name="cart">The cart.</param>
/// <returns>CartModel.</returns>
private CartModel CreateCartModel(CartHelper cart)
{
var model = cart.CreateCartModel(true);
model.ShippingEstimateModel.Countries = _countryClient.GetAllCountries();
return model;
}
/// <summary>
/// Does the add to cart.
/// </summary>
/// <param name="cartName">Name of the cart.</param>
/// <param name="qty">The qty.</param>
/// <param name="catalogItem">The catalog item.</param>
/// <param name="parentCatalogItem">The parent catalog item.</param>
/// <returns>LineItem.</returns>
private LineItem DoAddToCart(string cartName, decimal qty, Item catalogItem, Item parentCatalogItem)
{
LineItem addedLineItem = null;
// Check if Entry Object is null.
if (catalogItem != null)
{
var ch = GetCartHelper(cartName);
if (!string.Equals(cartName, CartHelper.WishListName, StringComparison.OrdinalIgnoreCase))
{
// add entry to the cart. If it's in the wish list, move it from the wish list to the cart.
var helper = GetCartHelper(CartHelper.WishListName);
var li = helper.LineItems.FirstOrDefault(item => item.CatalogItemId == catalogItem.ItemId);
if (li != null)
{
qty = li.Quantity;
helper.Remove(li);
// If wish list is empty, remove it from the database
if (helper.IsEmpty)
{
helper.Delete();
}
helper.SaveChanges();
}
}
// Add item to a cart.
addedLineItem = ch.AddItem(catalogItem, parentCatalogItem, qty, string.Equals(cartName, CartHelper.CompareListName, StringComparison.OrdinalIgnoreCase));
SaveChanges(ch);
}
return addedLineItem;
}
}
}