Example #1
0
        internal async Task <decimal> GetCartItemsAttributesWeightAsync(IList <OrganizedShoppingCartItem> cart, bool multipliedByQuantity = true)
        {
            Guard.NotNull(cart, nameof(cart));

            var rawAttributes = cart
                                .Where(x => x.Item.RawAttributes.HasValue())
                                .Select(x => x.Item.RawAttributes);

            var selection = new ProductVariantAttributeSelection(string.Empty);

            foreach (var cartItem in cart)
            {
                if (cartItem.Item.RawAttributes.IsEmpty() || cartItem.Item.Product.IsGiftCard)
                {
                    continue;
                }

                var attributeSelection = new ProductVariantAttributeSelection(cartItem.Item.RawAttributes);
                foreach (var attribute in attributeSelection.AttributesMap)
                {
                    if (attribute.Value.IsNullOrEmpty())
                    {
                        continue;
                    }

                    selection.AddAttribute(attribute.Key, attribute.Value.ToArray());
                }
            }

            var attributeValueIds = selection.GetAttributeValueIds();

            // Gets either all values of attributes without a product linkage
            // or linked products which are shipping enabled
            var query = _db.ProductVariantAttributeValues
                        .Include(x => x.ProductVariantAttribute)
                        .ThenInclude(x => x.Product)
                        .ApplyValueFilter(attributeValueIds)
                        .Where(x => x.ValueTypeId == (int)ProductVariantAttributeValueType.ProductLinkage &&
                               x.ProductVariantAttribute.Product != null &&
                               x.ProductVariantAttribute.Product.IsShippingEnabled ||
                               x.ValueTypeId != (int)ProductVariantAttributeValueType.ProductLinkage);

            // Calculates attributes weight
            // Get attributes without product linkage > add attribute weight adjustment
            var attributesWeight = await query
                                   .Where(x => x.ValueTypeId != (int)ProductVariantAttributeValueType.ProductLinkage)
                                   // TODO: (ms) (core) Test possible SumAsync SQL projection failure (IIF)
                                   .SumAsync(x => x.WeightAdjustment * (multipliedByQuantity ? x.Quantity : 1));

            // TODO: (ms) (core) needs to be tested with NullResult
            // Get attributes with product linkage > add product weigth
            attributesWeight += await query
                                .Where(x => x.ValueTypeId == (int)ProductVariantAttributeValueType.ProductLinkage)
                                .Select(x => new { x.ProductVariantAttribute.Product, x.Quantity })
                                .Where(x => x.Product != null && x.Product.IsShippingEnabled)
                                .SumAsync(x => x.Product.Weight * x.Quantity);

            return(attributesWeight);
        }
Example #2
0
        public virtual Task <IList <OrganizedShoppingCartItem> > GetCartItemsAsync(
            Customer customer         = null,
            ShoppingCartType cartType = ShoppingCartType.ShoppingCart,
            int storeId = 0)
        {
            customer ??= _workContext.CurrentCustomer;

            var cacheKey = CartItemsKey.FormatInvariant(customer.Id, (int)cartType, storeId);
            var result   = _requestCache.Get(cacheKey, async() =>
            {
                var cartItems = new List <ShoppingCartItem>();
                // TODO: (ms) (core) Do we need to check for ShoppingCartItems.Product.ProductVariantAttribute is loaded too? Would this direct access be even possible then?
                if (_db.IsCollectionLoaded(customer, x => x.ShoppingCartItems))
                {
                    var filteredCartItems = customer.ShoppingCartItems
                                            .Where(x => x.CustomerId == customer.Id && x.ShoppingCartTypeId == (int)cartType);

                    if (storeId > 0)
                    {
                        filteredCartItems = cartItems.Where(x => x.StoreId == storeId);
                    }

                    cartItems = filteredCartItems.ToList();
                }
                else
                {
                    // TODO: (core) Re-apply data to Customer.ShoppingCartItems collection to prevent reloads.
                    cartItems = await _db.ShoppingCartItems
                                .Include(x => x.Product)
                                .ThenInclude(x => x.ProductVariantAttributes)
                                .ApplyStandardFilter(cartType, storeId, customer)
                                .ToListAsync();
                }

                // Prefetch all product variant attributes
                var allAttributes    = new ProductVariantAttributeSelection(string.Empty);
                var allAttributeMaps = cartItems.SelectMany(x => x.AttributeSelection.AttributesMap);

                foreach (var attribute in allAttributeMaps)
                {
                    if (allAttributes.AttributesMap.Contains(attribute))
                    {
                        continue;
                    }

                    allAttributes.AddAttribute(attribute.Key, attribute.Value);
                }

                // TODO: (ms) (core) Check if this is sufficient and good prefetch -> what about caching or skipping already loaded?
                await _productAttributeMaterializer.MaterializeProductVariantAttributesAsync(allAttributes);

                return(await OrganizeCartItemsAsync(cartItems));
            });

            return(result);
        }
Example #3
0
        public virtual Task <List <OrganizedShoppingCartItem> > GetCartItemsAsync(
            Customer customer         = null,
            ShoppingCartType cartType = ShoppingCartType.ShoppingCart,
            int storeId = 0)
        {
            customer ??= _workContext.CurrentCustomer;

            var cacheKey = CartItemsKey.FormatInvariant(customer.Id, (int)cartType, storeId);
            var result   = _requestCache.Get(cacheKey, async() =>
            {
                var cartItems = new List <ShoppingCartItem>();
                if (_db.IsCollectionLoaded(customer, x => x.ShoppingCartItems))
                {
                    var filteredCartItems = customer.ShoppingCartItems
                                            .Where(x => x.CustomerId == customer.Id && x.ShoppingCartTypeId == (int)cartType);

                    if (storeId > 0)
                    {
                        filteredCartItems = cartItems.Where(x => x.StoreId == storeId);
                    }

                    cartItems = filteredCartItems.ToList();
                }
                else
                {
                    cartItems = await _db.ShoppingCartItems
                                .Include(x => x.Product)
                                .ThenInclude(x => x.ProductVariantAttributes)
                                .ApplyStandardFilter(cartType, storeId, customer)
                                .ToListAsync();

                    customer.ShoppingCartItems = cartItems;
                }

                // Prefetch all product variant attributes
                var allAttributes    = new ProductVariantAttributeSelection(string.Empty);
                var allAttributeMaps = cartItems.SelectMany(x => x.AttributeSelection.AttributesMap);

                foreach (var attribute in allAttributeMaps)
                {
                    if (allAttributes.AttributesMap.Contains(attribute))
                    {
                        continue;
                    }

                    allAttributes.AddAttribute(attribute.Key, attribute.Value);
                }

                await _productAttributeMaterializer.MaterializeProductVariantAttributesAsync(allAttributes);

                return(await OrganizeCartItemsAsync(cartItems));
            });

            return(result);
        }
Example #4
0
        public virtual Task <List <OrganizedShoppingCartItem> > GetCartItemsAsync(
            Customer customer         = null,
            ShoppingCartType cartType = ShoppingCartType.ShoppingCart,
            int storeId = 0)
        {
            customer ??= _workContext.CurrentCustomer;

            var cacheKey = CartItemsKey.FormatInvariant(customer.Id, (int)cartType, storeId);
            var result   = _requestCache.Get(cacheKey, async() =>
            {
                await _db.LoadCollectionAsync(customer, x => x.ShoppingCartItems, false, x =>
                {
                    return(x
                           .Include(x => x.Product)
                           .ThenInclude(x => x.ProductVariantAttributes));
                });

                var cartItems = customer.ShoppingCartItems.FilterByCartType(cartType, storeId);

                // Prefetch all product variant attributes
                var allAttributes    = new ProductVariantAttributeSelection(string.Empty);
                var allAttributeMaps = cartItems.SelectMany(x => x.AttributeSelection.AttributesMap);

                foreach (var attribute in allAttributeMaps)
                {
                    if (allAttributes.AttributesMap.Contains(attribute))
                    {
                        continue;
                    }

                    allAttributes.AddAttribute(attribute.Key, attribute.Value);
                }

                await _productAttributeMaterializer.MaterializeProductVariantAttributesAsync(allAttributes);

                return(await OrganizeCartItemsAsync(cartItems));
            });

            return(result);
        }