public override async Task <Result> Handle(RemoveCartPackageCommand request, CancellationToken cancellationToken)
        {
            User user = await _user.GetUserAsync();

            // 1. Get the cart
            Cart cart = await _context.Carts.SingleOrDefaultAsync(
                m => m.ShopId == request.ShopId && m.UserId == user.Id, cancellationToken);

            // 2. If the cart doesn't exist, it means there is no cart packages
            if (cart == null)
            {
                return(NotFound <Cart>());
            }

            // 3. Cart exist so we can query for the cart package
            CartPackage cartPackage = await _context.CartPackages.SingleOrDefaultAsync(
                m => m.PackageId == request.PackageId && m.CartId == cart.Id, cancellationToken);

            // 4. If the cart package doesn't exist, it means we cannot decrease the quantity
            if (cartPackage == null)
            {
                return(NotFound <CartPackage>());
            }

            // 5. We check if we are removing everything
            if (cartPackage.Quantity <= request.Quantity)
            {
                // 5.1 If 100% of the quantity the remove cart package
                _context.Remove(cartPackage);

                // 5.2 If we don't have any cart packages in the cart anymore, then we can delete the cart
                if (!await _context.CartPackages.AnyAsync(m => m.CartId == cart.Id, cancellationToken))
                {
                    _context.Remove(cart);
                }
            }
            else if (cartPackage.Quantity > request.Quantity)
            {
                // 5.1 If not 100% of the quantity, then  we are safe and we can decrease the quantity in cart package
                cartPackage.Quantity -= request.Quantity;
                _context.Update(cartPackage);
            }

            await _context.SaveChangesAsync(cancellationToken);

            return(Ok());
        }
        public override async Task <Result> Handle(AddCartPackageCommand request, CancellationToken cancellationToken)
        {
            // 1. Check if item is a service (itemId, packageId)
            if (await _context.Services.AnyAsync(m => m.Id == request.ItemId, cancellationToken))
            {
                return(NotFound <Item>(request.ItemId));
            }

            // 2. We get the package and the item
            Package package = await _context.Packages
                              .Include(m => m.Item)
                              .SingleOrDefaultAsync(m => m.Id == request.PackageId && m.ItemId == request.ItemId && m.Item.ShopId == request.ShopId, cancellationToken);

            if (package == null)
            {
                return(NotFound <Package>(request.PackageId));
            }

            // 3. Enough stocks ?
            if (package.Stocks < request.Quantity)
            {
                return(BadRequest($"Invalid quantity. Only {package.Stocks} stocks were available"));
            }

            User user = await _user.GetUserAsync();

            // 4. Get user cart for shop
            Cart cart = await _context.Carts.SingleOrDefaultAsync(m => m.ShopId == request.ShopId && m.UserId == user.Id, cancellationToken);

            if (cart == null)
            {
                // 4.1 Cart doesn't exist, we create one
                cart = new Cart(user, package.Item.ShopId);
                await _context.Carts.AddAsync(cart, cancellationToken);
            }

            // 5. We get the cart package from cart
            CartPackage cartPackage = await _context.CartPackages
                                      .SingleOrDefaultAsync(m => m.CartId == cart.Id && m.PackageId == request.PackageId, cancellationToken);

            if (cartPackage == null)
            {
                // 5.1 This package doesn't exist in the cart so we create one
                cartPackage = new CartPackage(cart, package, package.Price, request.Quantity);
                await _context.CartPackages.AddAsync(cartPackage, cancellationToken);
            }
            else
            {
                // 5.2 This package is already in the cart, so we check if the total quantity is still valid
                if (package.Stocks < cartPackage.Quantity + request.Quantity)
                {
                    return(BadRequest($"Invalid quantity. Only {package.Stocks - cartPackage.Quantity} stocks can be added to your cart"));
                }

                cartPackage.Quantity += request.Quantity;
                _context.CartPackages.Update(cartPackage);
            }

            // 6. If we go that far, it means everything is ok
            await _context.SaveChangesAsync(cancellationToken);

            return(Ok());
        }