File size: 4,388 Bytes
6db0915
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
using ECommerce.Model.Entities;
using ECommerce.Model.Repositories;
using ECommerce.Presenter.Presenters;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;

namespace Ecommerce_web_project.Controllers;

public class CartController : Controller
{
    private readonly CartPresenter _presenter;
    private readonly UserManager<IdentityUser> _userManager;
    private readonly ICustomerRepository _customerRepo;
    private readonly IRepository<Cart> _cartRepo;
    private readonly IRepository<CartItem> _cartItemRepo;

    public CartController(
        CartPresenter presenter,
        UserManager<IdentityUser> userManager,
        ICustomerRepository customerRepo,
        IRepository<Cart> cartRepo,
        IRepository<CartItem> cartItemRepo)
    {
        _presenter = presenter;
        _userManager = userManager;
        _customerRepo = customerRepo;
        _cartRepo = cartRepo;
        _cartItemRepo = cartItemRepo;
    }

    private async Task<List<CartItemSession>> GetEffectiveCartAsync()
    {
        if (User.Identity?.IsAuthenticated == true)
        {
            var user = await _userManager.GetUserAsync(User);
            if (user != null)
            {
                var customer = await _customerRepo.GetByUserIdAsync(user.Id);
                if (customer != null)
                {
                    var dbCart = (await _cartRepo.FindAsync(c => c.CustomerId == customer.Id)).FirstOrDefault();
                    if (dbCart != null)
                    {
                        var dbItems = await _cartItemRepo.FindAsync(i => i.CartId == dbCart.Id);
                        return dbItems.Select(i => new CartItemSession { ProductId = i.ProductId, Quantity = i.Quantity }).ToList();
                    }
                    return new List<CartItemSession>();
                }
            }
        }
        return JsonSerializer.Deserialize<List<CartItemSession>>(HttpContext.Session.GetString("Cart") ?? "[]") ?? new();
    }

    private async Task SaveEffectiveCartAsync(List<CartItemSession> items)
    {
        if (User.Identity?.IsAuthenticated == true)
        {
            var user = await _userManager.GetUserAsync(User);
            if (user != null)
            {
                var customer = await _customerRepo.GetByUserIdAsync(user.Id);
                if (customer != null)
                {
                    var dbCart = (await _cartRepo.FindAsync(c => c.CustomerId == customer.Id)).FirstOrDefault();
                    if (dbCart == null)
                    {
                        dbCart = new Cart { CustomerId = customer.Id };
                        await _cartRepo.AddAsync(dbCart);
                    }
                    var existingItems = await _cartItemRepo.FindAsync(i => i.CartId == dbCart.Id);
                    foreach (var old in existingItems)
                        await _cartItemRepo.DeleteAsync(old);
                    foreach (var item in items)
                        await _cartItemRepo.AddAsync(new CartItem { CartId = dbCart.Id, ProductId = item.ProductId, Quantity = item.Quantity });
                    return;
                }
            }
        }
        HttpContext.Session.SetString("Cart", JsonSerializer.Serialize(items));
    }

    public async Task<IActionResult> Index()
    {
        var items = await GetEffectiveCartAsync();
        var cart = _presenter.GetCart(items);
        return View(cart);
    }

    [HttpPost]
    public async Task<IActionResult> AddToCart(Guid productId, int quantity = 1)
    {
        var items = await GetEffectiveCartAsync();
        items = _presenter.AddToCart(items, productId, quantity);
        await SaveEffectiveCartAsync(items);
        return RedirectToAction("Index");
    }

    [HttpPost]
    public async Task<IActionResult> UpdateQuantity(Guid productId, int quantity)
    {
        var items = await GetEffectiveCartAsync();
        items = _presenter.UpdateQuantity(items, productId, quantity);
        await SaveEffectiveCartAsync(items);
        return RedirectToAction("Index");
    }

    [HttpPost]
    public async Task<IActionResult> Remove(Guid productId)
    {
        var items = await GetEffectiveCartAsync();
        items = _presenter.RemoveFromCart(items, productId);
        await SaveEffectiveCartAsync(items);
        return RedirectToAction("Index");
    }
}