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); }
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); }
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); }
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); }