// TODO: (ms) (core) Find other methods where navigation properties are (maybe) accessed > check for IsLoaded and use instead of db call // TODO: (ms) (core) Make sure Async methods (check calls of methods in services) are always awaited public virtual Task <int> CountCartItemsAsync( Customer customer = null, ShoppingCartType cartType = ShoppingCartType.ShoppingCart, int storeId = 0) { customer ??= _workContext.CurrentCustomer; if (_db.IsCollectionLoaded(customer, x => x.ShoppingCartItems)) { var cartItems = customer.ShoppingCartItems .Where(x => x.ParentItemId == null && x.ShoppingCartTypeId == (int)cartType); if (customer != null) { cartItems = cartItems.Where(x => x.CustomerId == customer.Id); } if (storeId > 0) { cartItems = cartItems.Where(x => x.StoreId == storeId); } return(Task.FromResult(cartItems.Sum(x => x.Quantity))); } return(_db.ShoppingCartItems .ApplyStandardFilter(cartType, storeId, customer) .Where(x => x.ParentItemId == null) .SumAsync(x => (int?)x.Quantity ?? 0)); }
/// <summary> /// Maps NOP data insto this model. /// </summary> /// <param name="customer">The NOP customer.</param> /// <param name="cartType">The cart type.</param> /// <param name="storeName">The store name.</param> public void Map(Customer customer, ShoppingCartType cartType, string storeName = null) { this.CustomerGuid = customer.CustomerGuid; this.CustomerId = customer.Id; this.Total = this.OrderTotalCalculationService.GetShoppingCartTotal(customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == cartType).ToList(), true, false); this.CustomerEmail = customer.IsGuest() ? string.Empty : customer.Email; this.ShoppingItems = this.GetShoppingItemsModels(customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == cartType).ToList()); this.IsAnonymous = customer.IsGuest(); this.IsDeleted = customer.Deleted; this.ShippingAddressId = (customer.ShippingAddress != null) ? customer.ShippingAddress.Id : (int?)null; if (customer.ShippingAddress != null) { this.ShippingName = customer.ShippingAddress.FirstName + " " + customer.ShippingAddress.LastName; var model = new AddressModel(); model.Map(customer.ShippingAddress); this.ShippingAddress = model; } this.BillingAddressId = (customer.BillingAddress != null) ? customer.BillingAddress.Id : (int?)null; if (customer.BillingAddress != null) { this.BillingName = customer.BillingAddress.FirstName + " " + customer.BillingAddress.LastName; var model = new AddressModel(); model.Map(customer.BillingAddress); this.BillingAddress = model; } this.Addresses = this.GetAddressModels(customer.Addresses); ///////////////////// this.StoreId = this.GetStoreId(storeName); this.PaymentInfo = this.GetPaymentInfoModel(customer, this.StoreId); this.ShippingInfo = this.GetShippingMethodModel(customer, this.StoreId); }
/// <summary> /// Finds and returns first matching product from shopping cart. /// </summary> /// <remarks> /// Products with the same identifier need to have matching attribute selections as well. /// </remarks> /// <param name="cart">Shopping cart to search in.</param> /// <param name="shoppingCartType">Shopping cart type to search in.</param> /// <param name="product">Product to search for.</param> /// <param name="selection">Attribute selection.</param> /// <param name="customerEnteredPrice">Customers entered price needs to match (if enabled by product).</param> /// <returns>Matching <see cref="OrganizedShoppingCartItem"/> or <c>null</c> if none was found.</returns> public static OrganizedShoppingCartItem FindItemInCart( this IList <OrganizedShoppingCartItem> cart, ShoppingCartType shoppingCartType, Product product, ProductVariantAttributeSelection selection, Money customerEnteredPrice) { Guard.NotNull(cart, nameof(cart)); Guard.NotNull(product, nameof(product)); // Return on product bundle with individual item pricing - too complex if (product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing) { return(null); } // Filter non group items from correct cart type, with matching product id and product type id var filteredCart = cart .Where(x => x.Item.ShoppingCartType == shoppingCartType && x.Item.ParentItemId == null && x.Item.Product.ProductTypeId == product.ProductTypeId && x.Item.ProductId == product.Id); // There could be multiple matching products with the same identifier but different attributes/selections (etc). // Ensure matching product infos are the same (attributes, gift card values (if it is gift card), customerEnteredPrice). foreach (var cartItem in filteredCart) { // Compare attribute selection var cartItemSelection = cartItem.Item.AttributeSelection; if (cartItemSelection != selection) { continue; } var currentProduct = cartItem.Item.Product; // Compare gift cards info values (if it is a gift card) if (currentProduct.IsGiftCard && (cartItemSelection.GiftCardInfo == null || selection.GiftCardInfo == null || cartItemSelection != selection)) { continue; } // Products with CustomerEntersPrice are equal if the price is the same. // But a system product may only be placed once in the shopping cart. if (currentProduct.CustomerEntersPrice && !currentProduct.IsSystemProduct && customerEnteredPrice.RoundedAmount != decimal.Round(cartItem.Item.CustomerEnteredPrice, customerEnteredPrice.DecimalDigits)) { continue; } // If we got this far, we found a matching product with the same values return(cartItem); } return(null); }
private List <ShoppingCartItemModel> GetCartItemModels(ShoppingCartType cartType, Customer customer) { decimal taxRate; var cart = customer.GetCartItems(cartType); var stores = Services.StoreService.GetAllStores().ToDictionary(x => x.Id, x => x); var result = cart.Select(sci => { stores.TryGetValue(sci.Item.StoreId, out var store); var model = new ShoppingCartItemModel { Id = sci.Item.Id, Store = store?.Name?.NaIfEmpty(), ProductId = sci.Item.ProductId, Quantity = sci.Item.Quantity, ProductName = sci.Item.Product.GetLocalized(x => x.Name), ProductTypeName = sci.Item.Product.GetProductTypeLabel(Services.Localization), ProductTypeLabelHint = sci.Item.Product.ProductTypeLabelHint, UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)), Total = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)), UpdatedOn = _dateTimeHelper.ConvertToUserTime(sci.Item.UpdatedOnUtc, DateTimeKind.Utc) }; return(model); }); return(result.ToList()); }
/// <summary> /// Gets the customers shopping cart items count async. /// </summary> /// <param name="customer">Customer of cart to be counted.</param> /// <param name="cartType">Shopping cart type.</param> /// <param name="storeId">Store identifier.</param> /// <returns>Number of items.</returns> public static Task <int> CountCartItemsAsync(this IQueryable <ShoppingCartItem> query, Customer customer, ShoppingCartType cartType = ShoppingCartType.ShoppingCart, int storeId = 0) { var db = query.GetDbContext <SmartDbContext>(); if (db.IsCollectionLoaded(customer, x => x.ShoppingCartItems)) { var cartItems = customer.ShoppingCartItems .Where(x => x.ParentItemId == null && x.ShoppingCartTypeId == (int)cartType); if (customer != null) { cartItems = cartItems.Where(x => x.CustomerId == customer.Id); } if (storeId > 0) { cartItems = cartItems.Where(x => x.StoreId == storeId); } return(Task.FromResult(cartItems.Sum(x => x.Quantity))); } return(query .ApplyStandardFilter(cartType, storeId, customer) .Where(x => x.ParentItemId == null) .SumAsync(x => (int?)x.Quantity ?? 0)); }
public IHttpActionResult UpdateShoppingCartItem([ModelBinder(typeof(JsonModelBinder <ShoppingCartItemDto>))] Delta <ShoppingCartItemDto> shoppingCartItemDelta) { // Here we display the errors if the validation has failed at some point. if (!ModelState.IsValid) { return(Error()); } // We kno that the id will be valid integer because the validation for this happens in the validator which is executed by the model binder. ShoppingCartItem shoppingCartItemForUpdate = _shoppingCartItemApiService.GetShoppingCartItem(int.Parse(shoppingCartItemDelta.Dto.Id)); if (shoppingCartItemForUpdate == null) { return(Error(HttpStatusCode.NotFound, "shopping_cart_item", "not found")); } // Here we make sure that the product id and the customer id won't be modified. int productId = shoppingCartItemForUpdate.ProductId; int customerId = shoppingCartItemForUpdate.CustomerId; shoppingCartItemDelta.Merge(shoppingCartItemForUpdate); shoppingCartItemForUpdate.ProductId = productId; shoppingCartItemForUpdate.CustomerId = customerId; if (!shoppingCartItemForUpdate.Product.IsRental) { shoppingCartItemForUpdate.RentalStartDateUtc = null; shoppingCartItemForUpdate.RentalEndDateUtc = null; } if (!string.IsNullOrEmpty(shoppingCartItemDelta.Dto.ShoppingCartType)) { ShoppingCartType shoppingCartType = (ShoppingCartType)Enum.Parse(typeof(ShoppingCartType), shoppingCartItemDelta.Dto.ShoppingCartType); shoppingCartItemForUpdate.ShoppingCartType = shoppingCartType; } // The update time is set in the service. _shoppingCartService.UpdateShoppingCartItem(shoppingCartItemForUpdate.Customer, shoppingCartItemForUpdate.Id, shoppingCartItemForUpdate.AttributesXml, shoppingCartItemForUpdate.CustomerEnteredPrice, shoppingCartItemForUpdate.RentalStartDateUtc, shoppingCartItemForUpdate.RentalEndDateUtc, shoppingCartItemForUpdate.Quantity); // Preparing the result dto of the new product category mapping ShoppingCartItemDto newShoppingCartItemDto = shoppingCartItemForUpdate.ToDto(); newShoppingCartItemDto.ProductDto = shoppingCartItemForUpdate.Product.ToDto(); newShoppingCartItemDto.CustomerDto = shoppingCartItemForUpdate.Customer.ToCustomerForShoppingCartItemDto(); newShoppingCartItemDto.ShoppingCartType = shoppingCartItemForUpdate.ShoppingCartType.ToString(); var shoppingCartsRootObject = new ShoppingCartItemsRootObject(); shoppingCartsRootObject.ShoppingCartItems.Add(newShoppingCartItemDto); var json = _jsonFieldsSerializer.Serialize(shoppingCartsRootObject, string.Empty); return(new RawJsonActionResult(json)); }
public static void ClearShoppingCart(ShoppingCartType shoppingCartType, Guid customerId) { SQLDataAccess.ExecuteNonQuery( "DELETE FROM Catalog.ShoppingCart WHERE ShoppingCartType = @ShoppingCartType and CustomerId = @CustomerId", CommandType.Text, new SqlParameter("@ShoppingCartType", (int)shoppingCartType), new SqlParameter("@CustomerId", customerId)); }
public static IEnumerable<ShoppingCartItem> Filter(this IEnumerable<ShoppingCartItem> shoppingCart, ShoppingCartType type, int? storeId = null) { var enumerable = shoppingCart.Where(x => x.ShoppingCartType == type); if (storeId.HasValue) enumerable = enumerable.Where(x => x.StoreId == storeId.Value); return enumerable; }
/// <summary> /// The DeleteShoppingCart. /// </summary> /// <param name="customerId">The customerId<see cref="int"/>.</param> /// <param name="shoppingCartType">The shoppingCartType<see cref="ShoppingCartType"/>.</param> /// <returns>The <see cref="Task{bool}"/>.</returns> public virtual async Task <bool> DeleteShoppingCart(int customerId = 0, ShoppingCartType shoppingCartType = ShoppingCartType.ShoppingCart) { if (customerId == 0) { throw new ArgumentNullException(nameof(customerId)); } return(await _basketRepository.DeleteShoppingCart(customerId, shoppingCartType)); }
public static int CountProductsInCart(this Customer customer, ShoppingCartType cartType, int? storeId = null) { int count = customer.ShoppingCartItems .Filter(cartType, storeId) .Where(x => x.ParentItemId == null) .Sum(x => x.Quantity); return count; }
public static int CountProductsInCart(this Customer customer, ShoppingCartType cartType, int?storeId = null) { int count = customer.ShoppingCartItems .Filter(cartType, storeId) .Where(x => x.ParentItemId == null) .Sum(x => x.Quantity); return(count); }
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); }
/// <summary> /// Validates required products (products which require some other products to be added to the cart) /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="storeId">Store identifier</param> /// <param name="automaticallyAddRequiredProductsIfEnabled">Automatically add required products if enabled</param> /// <returns>Warnings</returns> public virtual async Task <IList <string> > GetRequiredProductWarnings(Customer customer, ShoppingCartType shoppingCartType, Product product, string storeId) { if (customer == null) { throw new ArgumentNullException(nameof(customer)); } if (product == null) { throw new ArgumentNullException(nameof(product)); } var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartTypeId == shoppingCartType) .LimitPerStore(_shoppingCartSettings.SharedCartBetweenStores, storeId) .ToList(); var warnings = new List <string>(); if (product.RequireOtherProducts) { var requiredProducts = new List <Product>(); foreach (var id in product.ParseRequiredProductIds()) { var rp = await _productService.GetProductById(id); if (rp != null) { requiredProducts.Add(rp); } } foreach (var rp in requiredProducts) { //ensure that product is in the cart bool alreadyInTheCart = false; foreach (var sci in cart) { if (sci.ProductId == rp.Id) { alreadyInTheCart = true; break; } } //not in the cart if (!alreadyInTheCart) { warnings.Add(string.Format(_translationService.GetResource("ShoppingCart.RequiredProductWarning"), rp.GetTranslation(x => x.Name, _workContext.WorkingLanguage.Id))); } } } return(warnings); }
/// <summary> /// Validates shopping cart item (gift card) /// </summary> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <returns>Warnings</returns> public virtual IList <string> GetShoppingCartItemGiftCardWarnings(ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes) { if (productVariant == null) { throw new ArgumentNullException("productVariant"); } var warnings = new List <string>(); //gift cards if (productVariant.IsGiftCard) { string giftCardRecipientName = string.Empty; string giftCardRecipientEmail = string.Empty; string giftCardSenderName = string.Empty; string giftCardSenderEmail = string.Empty; string giftCardMessage = string.Empty; _productAttributeParser.GetGiftCardAttribute(selectedAttributes, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); if (String.IsNullOrEmpty(giftCardRecipientName)) { warnings.Add(_localizationService.GetResource("ShoppingCart.RecipientNameError")); } if (productVariant.GiftCardType == GiftCardType.Virtual) { //validate for virtual gift cards only if (String.IsNullOrEmpty(giftCardRecipientEmail) || !CommonHelper.IsValidEmail(giftCardRecipientEmail)) { warnings.Add(_localizationService.GetResource("ShoppingCart.RecipientEmailError")); } } if (String.IsNullOrEmpty(giftCardSenderName)) { warnings.Add(_localizationService.GetResource("ShoppingCart.SenderNameError")); } if (productVariant.GiftCardType == GiftCardType.Virtual) { //validate for virtual gift cards only if (String.IsNullOrEmpty(giftCardSenderEmail) || !CommonHelper.IsValidEmail(giftCardSenderEmail)) { warnings.Add(_localizationService.GetResource("ShoppingCart.SenderEmailError")); } } } return(warnings); }
public static int CountProductsInCart(this Customer customer, ShoppingCartType cartType, int?storeId = null) { if (customer != null) { var cartService = EngineContext.Current.Resolve <IShoppingCartService>(); var count = cartService.CountItems(customer, cartType, storeId); return(count); } return(0); }
/// <summary> /// The GetShoppingCart. /// </summary> /// <param name="customerId">The customerId<see cref="int"/>.</param> /// <param name="shoppingCartType">The shoppingCartType<see cref="ShoppingCartType"/>.</param> /// <returns>The <see cref="Task{ShoppingCart}"/>.</returns> public virtual async Task <ShoppingCart> GetShoppingCart(int customerId, ShoppingCartType shoppingCartType = ShoppingCartType.ShoppingCart) { var key = string.Format(ShoppingCartDefaults.ShoppingCartKey, customerId, (int)shoppingCartType); var cart = await _basketDbProvider.GetDatabase().StringGetAsync(key); if (cart.IsNullOrEmpty) { return(null); } return(JsonConvert.DeserializeObject <ShoppingCart>(cart)); }
public static void ClearShoppingCart(ShoppingCartType shoppingCartType, Guid customerId) { SQLDataAccess.ExecuteNonQuery ("DELETE FROM Catalog.ShoppingCart WHERE ShoppingCartTypeId = @ShoppingCartTypeId and CustomerId = @CustomerId", CommandType.Text, new SqlParameter { ParameterName = "@ShoppingCartTypeId", Value = shoppingCartType }, new SqlParameter { ParameterName = "@CustomerId", Value = customerId } ); }
public virtual IList <string> GetStandardWarnings(User user, ShoppingCartType shoppingCartType, Item item, int quantity) { if (user == null) { throw new ArgumentNullException("user"); } if (item == null) { throw new ArgumentNullException("item"); } var warnings = new List <string>(); // удален if (item.Deleted) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductDeleted")); } // не опубликован if (!item.Published) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished")); } // время торгов окончено bool availableStartDateError = false; if (item.AuctionStartDate.HasValue) { DateTime now = DateTime.UtcNow; DateTime availableStartDateTime = DateTime.SpecifyKind(item.AuctionStartDate.Value, DateTimeKind.Utc); if (availableStartDateTime.CompareTo(now) > 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); availableStartDateError = true; } } if (item.AuctionEndDate.HasValue && !availableStartDateError) { DateTime now = DateTime.UtcNow; DateTime availableEndDateTime = DateTime.SpecifyKind(item.AuctionEndDate.Value, DateTimeKind.Utc); if (availableEndDateTime.CompareTo(now) < 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); } } return(warnings); }
public static ShoppingCart GetShoppingCart(ShoppingCartType shoppingCartType, Guid customerId) { var templist = SQLDataAccess.ExecuteReadList( "SELECT * FROM Catalog.ShoppingCart WHERE ShoppingCartType = @ShoppingCartType and CustomerId = @CustomerId", CommandType.Text, GetFromReader, new SqlParameter("@ShoppingCartType", (int)shoppingCartType), new SqlParameter("@CustomerId", customerId)); var shoppingCart = new ShoppingCart(); shoppingCart.AddRange(templist); return(shoppingCart); }
/// <summary> /// Add a product to shopping cart without validation /// </summary> /// <param name="customer">Customer</param> /// <param name="product">Product</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="storeId">Store identifier</param> /// <param name="quantity">Quantity</param> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="customerEnteredPrice">The price enter by a customer</param> /// <param name="rentalStartDate">Rental start date</param> /// <param name="rentalEndDate">Rental end date</param> /// <param name="addRequiredProducts">Whether to add required products</param> /// <returns>Warnings</returns> public static ShoppingCartItem AddShoppingCartItem(this IShoppingCartService shoppingCartService, ICustomerService customerService, Customer customer, int productId, ShoppingCartType shoppingCartType, int storeId, int quantity = 1, string attributesXml = null, decimal customerEnteredPrice = decimal.Zero, DateTime?rentalStartDate = null, DateTime?rentalEndDate = null, bool addRequiredProducts = true) { if (customer == null) { throw new ArgumentNullException(nameof(customer)); } //reset checkout info customerService.ResetCheckoutData(customer, storeId); var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartType == shoppingCartType) .LimitPerStore(storeId) .ToList(); var now = DateTime.UtcNow; var shoppingCartItem = new ShoppingCartItem { ShoppingCartType = shoppingCartType, StoreId = storeId, ProductId = productId, AttributesXml = attributesXml, CustomerEnteredPrice = customerEnteredPrice, Quantity = quantity, RentalStartDateUtc = rentalStartDate, RentalEndDateUtc = rentalEndDate, CreatedOnUtc = now, UpdatedOnUtc = now }; customer.ShoppingCartItems.Add(shoppingCartItem); customerService.UpdateCustomer(customer); //updated "HasShoppingCartItems" property used for performance optimization customer.HasShoppingCartItems = customer.ShoppingCartItems.Any(); customerService.UpdateCustomer(customer); //event notification //_eventPublisher.EntityInserted(shoppingCartItem); return(shoppingCartItem); }
public virtual IList <string> ValidateCartItemsMaximum(ShoppingCartType cartType, int cartItemsCount) { var warnings = new List <string>(); if (cartType == ShoppingCartType.ShoppingCart && cartItemsCount >= _cartSettings.MaximumShoppingCartItems) { warnings.Add(T("ShoppingCart.MaximumShoppingCartItems")); } else if (cartType == ShoppingCartType.Wishlist && cartItemsCount >= _cartSettings.MaximumWishlistItems) { warnings.Add(T("ShoppingCart.MaximumWishlistItems")); } return(warnings); }
public virtual IList <string> GetShoppingCartItemGiftVoucherWarnings(ShoppingCartType shoppingCartType, Product product, IList <CustomAttribute> attributes) { if (product == null) { throw new ArgumentNullException(nameof(product)); } var warnings = new List <string>(); //gift vouchers if (product.IsGiftVoucher) { _productAttributeParser.GetGiftVoucherAttribute(attributes, out string giftVoucherRecipientName, out string giftVoucherRecipientEmail, out string giftVoucherSenderName, out string giftVoucherSenderEmail, out string giftVoucherMessage); if (string.IsNullOrEmpty(giftVoucherRecipientName)) { warnings.Add(_translationService.GetResource("ShoppingCart.RecipientNameError")); } if (product.GiftVoucherTypeId == GiftVoucherType.Virtual) { //validate for virtual gift vouchers only if (string.IsNullOrEmpty(giftVoucherRecipientEmail) || !CommonHelper.IsValidEmail(giftVoucherRecipientEmail)) { warnings.Add(_translationService.GetResource("ShoppingCart.RecipientEmailError")); } } if (string.IsNullOrEmpty(giftVoucherSenderName)) { warnings.Add(_translationService.GetResource("ShoppingCart.SenderNameError")); } if (product.GiftVoucherTypeId == GiftVoucherType.Virtual) { //validate for virtual gift vouchers only if (string.IsNullOrEmpty(giftVoucherSenderEmail) || !CommonHelper.IsValidEmail(giftVoucherSenderEmail)) { warnings.Add(_translationService.GetResource("ShoppingCart.SenderEmailError")); } } } return(warnings); }
/// <summary> /// Standard filter for shopping cart. /// Applies store and type filter, includes hidden (<see cref="CheckoutAttribute.IsActive"/>) attributes /// and orders query by <see cref="CheckoutAttribute.DisplayOrder"/> /// </summary> public static IQueryable <ShoppingCartItem> ApplyStandardFilter( this IQueryable <ShoppingCartItem> query, ShoppingCartType type = ShoppingCartType.ShoppingCart, int storeId = 0) { Guard.NotNull(query, nameof(query)); if (storeId > 0) { query = query.Where(x => x.StoreId == storeId); } query = query.Where(x => x.ShoppingCartTypeId == (int)type); return(query); }
public virtual IList <string> GetShoppingCartItemWarnings(User user, ShoppingCartType shoppingCartType, Item item, int quantity = 1, bool getStandardWarnings = true) { if (item == null) { throw new ArgumentNullException("item"); } var warnings = new List <string>(); if (getStandardWarnings) { warnings.AddRange(GetStandardWarnings(user, shoppingCartType, item, quantity)); } return(warnings); }
public virtual async Task <IActionResult> Get(int customerId, ShoppingCartType shoppingCartType) { var shoppingCart = await _shoppingCartService.GetShoppingCart(customerId, shoppingCartType); if (shoppingCart.ShoppingCartItems != null && shoppingCart.ShoppingCartItems.Any()) { foreach (var cartItem in shoppingCart.ShoppingCartItems) { var coupon = await _discountProtoServiceClient.GetDiscountAsync(new GetDiscountRequest { ProductId = cartItem.ProductId }); _shoppingCartService.CalculateCartItemPrice(cartItem, coupon.Amount); } } var result = new SuccessDataResult(shoppingCart); return(Ok(result)); }
public static ShoppingCart GetShoppingCart(ShoppingCartType shoppingCartType, Guid customerId) { var templist = SQLDataAccess.ExecuteReadList <ShoppingCartItem> ("SELECT * FROM Catalog.ShoppingCart WHERE ShoppingCartTypeId = @ShoppingCartTypeId and CustomerId = @CustomerId", CommandType.Text, GetFromReader, new SqlParameter { ParameterName = "@ShoppingCartTypeId", Value = (int)shoppingCartType }, new SqlParameter { ParameterName = "@CustomerId", Value = customerId } ); var shoppingCart = new ShoppingCart(); shoppingCart.AddRange(templist); return(shoppingCart); }
public virtual bool ValidateItemsMaximumCartQuantity(ShoppingCartType cartType, int cartItemsCount, IList <string> warnings) { Guard.NotNull(warnings, nameof(warnings)); var isValid = true; if (cartType == ShoppingCartType.ShoppingCart && cartItemsCount >= _cartSettings.MaximumShoppingCartItems) { isValid = false; warnings.Add(T("ShoppingCart.MaximumShoppingCartItems")); } else if (cartType == ShoppingCartType.Wishlist && cartItemsCount >= _cartSettings.MaximumWishlistItems) { isValid = false; warnings.Add(T("ShoppingCart.MaximumWishlistItems")); } return(isValid); }
public virtual void AddToCart(Customer customer, Product product, ShoppingCartType shoppingCartType, int quantity) { if (customer == null) throw new ArgumentNullException("customer"); if (product == null) throw new ArgumentNullException("product"); var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartType == shoppingCartType) .ToList(); var shoppingCartItem = FindShoppingCartItemInTheCart(cart, shoppingCartType, product); if (shoppingCartItem != null) { //update existing shopping cart item shoppingCartItem.Quantity = shoppingCartItem.Quantity + quantity; shoppingCartItem.UpdatedOnUtc = DateTime.UtcNow; _customerService.UpdateCustomer(customer); } else { //new shopping cart item DateTime now = DateTime.UtcNow; shoppingCartItem = new ShoppingCartItem() { ShoppingCartType = shoppingCartType, Product = product, ItemPrice = product.Price, Quantity = quantity, CreatedOnUtc = now, UpdatedOnUtc = now }; customer.ShoppingCartItems.Add(shoppingCartItem); _customerService.UpdateCustomer(customer); //updated "HasShoppingCartItems" property used for performance optimization customer.HasShoppingCartItems = customer.ShoppingCartItems.Count > 0; _customerService.UpdateCustomer(customer); } }
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); }
/// <summary> /// Validates shopping cart item /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="storeId">Store identifier</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">Customer entered price</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param> /// <param name="getStandardWarnings">A value indicating whether we should validate a product variant for standard properties</param> /// <param name="getAttributesWarnings">A value indicating whether we should validate product attributes</param> /// <param name="getGiftCardWarnings">A value indicating whether we should validate gift card properties</param> /// <param name="getRequiredProductVariantWarnings">A value indicating whether we should validate required product variants (product variants which require other variant to be added to the cart)</param> /// <returns>Warnings</returns> public virtual IList <string> GetShoppingCartItemWarnings(Customer customer, ShoppingCartType shoppingCartType, ProductVariant productVariant, int storeId, string selectedAttributes, decimal customerEnteredPrice, int quantity, bool automaticallyAddRequiredProductVariantsIfEnabled, bool getStandardWarnings = true, bool getAttributesWarnings = true, bool getGiftCardWarnings = true, bool getRequiredProductVariantWarnings = true) { if (productVariant == null) { throw new ArgumentNullException("productVariant"); } var warnings = new List <string>(); //standard properties if (getStandardWarnings) { warnings.AddRange(GetStandardWarnings(customer, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice, quantity)); } //selected attributes if (getAttributesWarnings) { warnings.AddRange(GetShoppingCartItemAttributeWarnings(shoppingCartType, productVariant, selectedAttributes)); } //gift cards if (getGiftCardWarnings) { warnings.AddRange(GetShoppingCartItemGiftCardWarnings(shoppingCartType, productVariant, selectedAttributes)); } //required product variants if (getRequiredProductVariantWarnings) { warnings.AddRange(GetRequiredProductVariantWarnings(customer, shoppingCartType, productVariant, storeId, automaticallyAddRequiredProductVariantsIfEnabled)); } return(warnings); }
/// <summary> /// Applies standard filter for shopping cart item. /// Applies store filter, shopping cart type and customer mapping filter. /// </summary> /// <returns> /// Orders query by ID /// </returns> public static IOrderedQueryable <ShoppingCartItem> ApplyStandardFilter( this IQueryable <ShoppingCartItem> query, ShoppingCartType type = ShoppingCartType.ShoppingCart, int storeId = 0, Customer customer = null) { Guard.NotNull(query, nameof(query)); if (storeId > 0) { query = query.Where(x => x.StoreId == storeId); } if (customer != null) { query = query.Where(x => x.CustomerId == customer.Id); } return(query .Where(x => x.ShoppingCartTypeId == (int)type) .OrderByDescending(x => x.Id)); }
public virtual ShoppingCartItem FindShoppingCartItemInTheCart(IList <ShoppingCartItem> shoppingCart, ShoppingCartType shoppingCartType, Item item) { if (shoppingCart == null) { throw new ArgumentNullException("shoppingCart"); } if (item == null) { throw new ArgumentNullException("item"); } foreach (var sci in shoppingCart.Where(a => a.ShoppingCartType == shoppingCartType)) { if (sci.ItemId == item.Id) { return(sci); } } return(null); }
/// <summary> /// Validates shopping cart item /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="storeId">Store identifier</param> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="customerEnteredPrice">Customer entered price</param> /// <param name="rentalStartDate">Rental start date</param> /// <param name="rentalEndDate">Rental end date</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductsIfEnabled">Automatically add required products if enabled</param> /// <param name="getStandardWarnings">A value indicating whether we should validate a product for standard properties</param> /// <param name="getAttributesWarnings">A value indicating whether we should validate product attributes</param> /// <param name="getGiftCardWarnings">A value indicating whether we should validate gift card properties</param> /// <param name="getRequiredProductWarnings">A value indicating whether we should validate required products (products which require other products to be added to the cart)</param> /// <param name="getRentalWarnings">A value indicating whether we should validate rental properties</param> /// <returns>Warnings</returns> public virtual IList<string> GetShoppingCartItemWarnings(Customer customer, ShoppingCartType shoppingCartType, Product product, int storeId, string attributesXml, decimal customerEnteredPrice, DateTime? rentalStartDate = null, DateTime? rentalEndDate = null, int quantity = 1, bool automaticallyAddRequiredProductsIfEnabled = true, bool getStandardWarnings = true, bool getAttributesWarnings = true, bool getGiftCardWarnings = true, bool getRequiredProductWarnings = true, bool getRentalWarnings = true) { if (product == null) throw new ArgumentNullException("product"); var warnings = new List<string>(); //standard properties if (getStandardWarnings) warnings.AddRange(GetStandardWarnings(customer, shoppingCartType, product, attributesXml, customerEnteredPrice, quantity)); //selected attributes if (getAttributesWarnings) warnings.AddRange(GetShoppingCartItemAttributeWarnings(customer, shoppingCartType, product, quantity, attributesXml)); //gift cards if (getGiftCardWarnings) warnings.AddRange(GetShoppingCartItemGiftCardWarnings(shoppingCartType, product, attributesXml)); //required products if (getRequiredProductWarnings) warnings.AddRange(GetRequiredProductWarnings(customer, shoppingCartType, product, storeId, automaticallyAddRequiredProductsIfEnabled)); //rental products if (getRentalWarnings) warnings.AddRange(GetRentalProductWarnings(product, rentalStartDate, rentalEndDate)); return warnings; }
/// <summary> /// Validates shopping cart item attributes /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="quantity">Quantity</param> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="ignoreNonCombinableAttributes">A value indicating whether we should ignore non-combinable attributes</param> /// <returns>Warnings</returns> public virtual IList<string> GetShoppingCartItemAttributeWarnings(Customer customer, ShoppingCartType shoppingCartType, Product product, int quantity = 1, string attributesXml = "", bool ignoreNonCombinableAttributes = false) { if (product == null) throw new ArgumentNullException("product"); var warnings = new List<string>(); //ensure it's our attributes var attributes1 = _productAttributeParser.ParseProductAttributeMappings(attributesXml); if (ignoreNonCombinableAttributes) { attributes1 = attributes1.Where(x => !x.IsNonCombinable()).ToList(); } foreach (var attribute in attributes1) { if (attribute.Product != null) { if (attribute.Product.ID != product.ID) { warnings.Add("Attribute error"); } } else { warnings.Add("Attribute error"); return warnings; } } //validate required product attributes (whether they're chosen/selected/entered) var attributes2 = _productAttributeService.GetProductAttributeMappingsByProductId(product.ID); if (ignoreNonCombinableAttributes) { attributes2 = attributes2.Where(x => !x.IsNonCombinable()).ToList(); } foreach (var a2 in attributes2) { if (a2.IsRequired) { bool found = false; //selected product attributes foreach (var a1 in attributes1) { if (a1.ID == a2.ID) { var attributeValuesStr = _productAttributeParser.ParseValues(attributesXml, a1.ID); foreach (string str1 in attributeValuesStr) { if (!String.IsNullOrEmpty(str1.Trim())) { found = true; break; } } } } //if not found if (!found) { var notFoundWarning = !string.IsNullOrEmpty(a2.TextPrompt) ? a2.TextPrompt : string.Format(_localizationService.GetResource("ShoppingCart.SelectAttribute"), a2.ProductAttribute.GetLocalized(a => a.Name)); warnings.Add(notFoundWarning); } } if (a2.AttributeControlType == AttributeControlType.ReadonlyCheckboxes) { //customers cannot edit read-only attributes var allowedReadOnlyValueIds = _productAttributeService.GetProductAttributeValues(a2.ID) .Where(x => x.IsPreSelected) .Select(x => x.ID) .ToArray(); var selectedReadOnlyValueIds = _productAttributeParser.ParseProductAttributeValues(attributesXml) .Where(x => x.ProductAttributeMappingId == a2.ID) .Select(x => x.ID) .ToArray(); if (!CommonHelper.ArraysEqual(allowedReadOnlyValueIds, selectedReadOnlyValueIds)) { warnings.Add("You cannot change read-only values"); } } } //validation rules foreach (var pam in attributes2) { if (!pam.ValidationRulesAllowed()) continue; //minimum length if (pam.ValidationMinLength.HasValue) { if (pam.AttributeControlType == AttributeControlType.TextBox || pam.AttributeControlType == AttributeControlType.MultilineTextbox) { var valuesStr = _productAttributeParser.ParseValues(attributesXml, pam.ID); var enteredText = valuesStr.FirstOrDefault(); int enteredTextLength = String.IsNullOrEmpty(enteredText) ? 0 : enteredText.Length; if (pam.ValidationMinLength.Value > enteredTextLength) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.TextboxMinimumLength"), pam.ProductAttribute.GetLocalized(a => a.Name), pam.ValidationMinLength.Value)); } } } //maximum length if (pam.ValidationMaxLength.HasValue) { if (pam.AttributeControlType == AttributeControlType.TextBox || pam.AttributeControlType == AttributeControlType.MultilineTextbox) { var valuesStr = _productAttributeParser.ParseValues(attributesXml, pam.ID); var enteredText = valuesStr.FirstOrDefault(); int enteredTextLength = String.IsNullOrEmpty(enteredText) ? 0 : enteredText.Length; if (pam.ValidationMaxLength.Value < enteredTextLength) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.TextboxMaximumLength"), pam.ProductAttribute.GetLocalized(a => a.Name), pam.ValidationMaxLength.Value)); } } } } if (warnings.Count > 0) return warnings; //validate bundled products var attributeValues = _productAttributeParser.ParseProductAttributeValues(attributesXml); foreach (var attributeValue in attributeValues) { if (attributeValue.AttributeValueType == AttributeValueType.AssociatedToProduct) { if (ignoreNonCombinableAttributes && attributeValue.ProductAttributeMapping.IsNonCombinable()) continue; //associated product (bundle) var associatedProduct = _productService.GetProductById(attributeValue.AssociatedProductId); if (associatedProduct != null) { var totalQty = quantity * attributeValue.Quantity; var associatedProductWarnings = GetShoppingCartItemWarnings(customer, shoppingCartType, associatedProduct, _storeContext.CurrentStore.ID, "", decimal.Zero, null, null, totalQty, false); foreach (var associatedProductWarning in associatedProductWarnings) { var attributeName = attributeValue.ProductAttributeMapping.ProductAttribute.GetLocalized(a => a.Name); var attributeValueName = attributeValue.GetLocalized(a => a.Name); warnings.Add(string.Format( _localizationService.GetResource("ShoppingCart.AssociatedAttributeWarning"), attributeName, attributeValueName, associatedProductWarning)); } } else { warnings.Add(string.Format("Associated product cannot be loaded - {0}", attributeValue.AssociatedProductId)); } } } return warnings; }
/// <summary> /// Validates a product variant for standard properties /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">Customer entered price</param> /// <param name="quantity">Quantity</param> /// <returns>Warnings</returns> public virtual IList<string> GetStandardWarnings(Customer customer, ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes, decimal customerEnteredPrice, int quantity) { if (customer == null) throw new ArgumentNullException("customer"); if (productVariant == null) throw new ArgumentNullException("productVariant"); var warnings = new List<string>(); var product = productVariant.Product; if (product == null) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CannotLoadProduct"), productVariant.ProductId)); return warnings; } //deleted? if (product.Deleted || productVariant.Deleted) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductDeleted")); return warnings; } //published? if (!product.Published || !productVariant.Published) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished")); } //ACL if (!_aclService.Authorize(product, customer)) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished")); } //disabled "add to cart" button if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.DisableBuyButton) { warnings.Add(_localizationService.GetResource("ShoppingCart.BuyingDisabled")); } //disabled "add to wishlist" button if (shoppingCartType == ShoppingCartType.Wishlist && productVariant.DisableWishlistButton) { warnings.Add(_localizationService.GetResource("ShoppingCart.WishlistDisabled")); } //call for price if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.CallForPrice) { warnings.Add(_localizationService.GetResource("Products.CallForPrice")); } //customer entered price if (productVariant.CustomerEntersPrice) { if (customerEnteredPrice < productVariant.MinimumCustomerEnteredPrice || customerEnteredPrice > productVariant.MaximumCustomerEnteredPrice) { decimal minimumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MinimumCustomerEnteredPrice, _workContext.WorkingCurrency); decimal maximumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MaximumCustomerEnteredPrice, _workContext.WorkingCurrency); warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CustomerEnteredPrice.RangeError"), _priceFormatter.FormatPrice(minimumCustomerEnteredPrice, false, false), _priceFormatter.FormatPrice(maximumCustomerEnteredPrice, false, false))); } } //quantity validation var hasQtyWarnings = false; if (quantity < productVariant.OrderMinimumQuantity) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MinimumQuantity"), productVariant.OrderMinimumQuantity)); hasQtyWarnings = true; } if (quantity > productVariant.OrderMaximumQuantity) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumQuantity"), productVariant.OrderMaximumQuantity)); hasQtyWarnings = true; } var allowedQuantities = productVariant.ParseAllowedQuatities(); if (allowedQuantities.Length > 0 && !allowedQuantities.Contains(quantity)) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.AllowedQuantities"), string.Join(", ", allowedQuantities))); } var validateOutOfStock = shoppingCartType == ShoppingCartType.ShoppingCart || !_shoppingCartSettings.AllowOutOfStockItemsToBeAddedToWishlist; if (validateOutOfStock && !hasQtyWarnings) { switch (productVariant.ManageInventoryMethod) { case ManageInventoryMethod.DontManageStock: { } break; case ManageInventoryMethod.ManageStock: { if ((BackorderMode)productVariant.BackorderMode == BackorderMode.NoBackorders) { if (productVariant.StockQuantity < quantity) { int maximumQuantityCanBeAdded = productVariant.StockQuantity; if (maximumQuantityCanBeAdded <= 0) warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock")); else warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded)); } } } break; case ManageInventoryMethod.ManageStockByAttributes: { var combination = productVariant .ProductVariantAttributeCombinations .FirstOrDefault(x => _productAttributeParser.AreProductAttributesEqual(x.AttributesXml, selectedAttributes)); if (combination != null && !combination.AllowOutOfStockOrders && combination.StockQuantity < quantity) { int maximumQuantityCanBeAdded = combination.StockQuantity; if (maximumQuantityCanBeAdded <= 0) warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock")); else warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded)); } } break; default: break; } } //availability dates bool availableStartDateError = false; if (productVariant.AvailableStartDateTimeUtc.HasValue) { DateTime now = DateTime.UtcNow; DateTime availableStartDateTime = DateTime.SpecifyKind(productVariant.AvailableStartDateTimeUtc.Value, DateTimeKind.Utc); if (availableStartDateTime.CompareTo(now) > 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); availableStartDateError = true; } } if (productVariant.AvailableEndDateTimeUtc.HasValue && !availableStartDateError) { DateTime now = DateTime.UtcNow; DateTime availableEndDateTime = DateTime.SpecifyKind(productVariant.AvailableEndDateTimeUtc.Value, DateTimeKind.Utc); if (availableEndDateTime.CompareTo(now) < 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); } } return warnings; }
/// <summary> /// Validates shopping cart item (gift card) /// </summary> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <returns>Warnings</returns> public virtual IList<string> GetShoppingCartItemGiftCardWarnings(ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes) { if (productVariant == null) throw new ArgumentNullException("productVariant"); var warnings = new List<string>(); //gift cards if (productVariant.IsGiftCard) { string giftCardRecipientName = string.Empty; string giftCardRecipientEmail = string.Empty; string giftCardSenderName = string.Empty; string giftCardSenderEmail = string.Empty; string giftCardMessage = string.Empty; _productAttributeParser.GetGiftCardAttribute(selectedAttributes, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); if (String.IsNullOrEmpty(giftCardRecipientName)) warnings.Add(_localizationService.GetResource("ShoppingCart.RecipientNameError")); if (productVariant.GiftCardType == GiftCardType.Virtual) { //validate for virtual gift cards only if (String.IsNullOrEmpty(giftCardRecipientEmail) || !CommonHelper.IsValidEmail(giftCardRecipientEmail)) warnings.Add(_localizationService.GetResource("ShoppingCart.RecipientEmailError")); } if (String.IsNullOrEmpty(giftCardSenderName)) warnings.Add(_localizationService.GetResource("ShoppingCart.SenderNameError")); if (productVariant.GiftCardType == GiftCardType.Virtual) { //validate for virtual gift cards only if (String.IsNullOrEmpty(giftCardSenderEmail) || !CommonHelper.IsValidEmail(giftCardSenderEmail)) warnings.Add(_localizationService.GetResource("ShoppingCart.SenderEmailError")); } } return warnings; }
/// <summary> /// Validates required product variants (product variants which require other variant to be added to the cart) /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param> /// <returns>Warnings</returns> public virtual IList<string> GetRequiredProductVariantWarnings(Customer customer, ShoppingCartType shoppingCartType, ProductVariant productVariant, bool automaticallyAddRequiredProductVariantsIfEnabled) { if (customer == null) throw new ArgumentNullException("customer"); if (productVariant == null) throw new ArgumentNullException("productVariant"); var cart = customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == shoppingCartType).ToList(); var warnings = new List<string>(); if (productVariant.RequireOtherProducts) { var requiredProductVariants = new List<ProductVariant>(); foreach (var id in productVariant.ParseRequiredProductVariantIds()) { var rpv = _productService.GetProductVariantById(id); if (rpv != null) requiredProductVariants.Add(rpv); } foreach (var rpv in requiredProductVariants) { //ensure that product is in the cart bool alreadyInTheCart = false; foreach (var sci in cart) { if (sci.ProductVariantId == rpv.Id) { alreadyInTheCart = true; break; } } //not in the cart if (!alreadyInTheCart) { string fullProductName = ""; if (!String.IsNullOrEmpty(rpv.GetLocalized(x => x.Name))) fullProductName = string.Format("{0} ({1})", rpv.Product.GetLocalized(x => x.Name), rpv.GetLocalized(x => x.Name)); else fullProductName = rpv.Product.GetLocalized(x => x.Name); if (productVariant.AutomaticallyAddRequiredProductVariants) { //add to cart (if possible) if (automaticallyAddRequiredProductVariantsIfEnabled) { //pass 'false' for 'automaticallyAddRequiredProductVariantsIfEnabled' to prevent circular references var addToCartWarnings = AddToCart(customer, rpv, shoppingCartType, "", decimal.Zero, 1, false); if (addToCartWarnings.Count > 0) { //a product wasn't atomatically added for some reasons //don't display specific errors from 'addToCartWarnings' variable //display only generic error warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), fullProductName)); } } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), fullProductName)); } } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), fullProductName)); } } } } return warnings; }
public static void ClearShoppingCart(ShoppingCartType shoppingCartType) { ClearShoppingCart(shoppingCartType, CustomerSession.CustomerId); }
/// <summary> /// Add a product to shopping cart /// </summary> /// <param name="customer">Customer</param> /// <param name="product">Product</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="storeId">Store identifier</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">The price enter by a customer</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductsIfEnabled">Automatically add required products if enabled</param> /// <param name="shoppingCartItemId">Identifier fo the new shopping cart item</param> /// <param name="parentItemId">Identifier of the parent shopping cart item</param> /// <param name="bundleItem">Product bundle item</param> /// <returns>Warnings</returns> public virtual IList<string> AddToCart(Customer customer, Product product, ShoppingCartType shoppingCartType, int storeId, string selectedAttributes, decimal customerEnteredPrice, int quantity, bool automaticallyAddRequiredProductsIfEnabled, out int shoppingCartItemId, int? parentItemId = null, ProductBundleItem bundleItem = null) { shoppingCartItemId = 0; if (customer == null) throw new ArgumentNullException("customer"); if (product == null) throw new ArgumentNullException("product"); var warnings = new List<string>(); if (shoppingCartType == ShoppingCartType.ShoppingCart && !_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart, customer)) { warnings.Add("Shopping cart is disabled"); return warnings; } if (shoppingCartType == ShoppingCartType.Wishlist && !_permissionService.Authorize(StandardPermissionProvider.EnableWishlist, customer)) { warnings.Add("Wishlist is disabled"); return warnings; } if (quantity <= 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive")); return warnings; } if (parentItemId.HasValue && (parentItemId.Value == 0 || bundleItem == null || bundleItem.Id == 0)) { warnings.Add(_localizationService.GetResource("ShoppingCart.Bundle.BundleItemNotFound").FormatWith(bundleItem.GetLocalizedName())); return warnings; } //reset checkout info _customerService.ResetCheckoutData(customer, storeId); var cart = customer.GetCartItems(shoppingCartType, storeId); OrganizedShoppingCartItem shoppingCartItem = null; if (bundleItem == null) { shoppingCartItem = FindShoppingCartItemInTheCart(cart, shoppingCartType, product, selectedAttributes, customerEnteredPrice); } if (shoppingCartItem != null) { //update existing shopping cart item int newQuantity = shoppingCartItem.Item.Quantity + quantity; warnings.AddRange( GetShoppingCartItemWarnings(customer, shoppingCartType, product, storeId, selectedAttributes, customerEnteredPrice, newQuantity, automaticallyAddRequiredProductsIfEnabled, bundleItem: bundleItem) ); if (warnings.Count == 0) { shoppingCartItem.Item.AttributesXml = selectedAttributes; shoppingCartItem.Item.Quantity = newQuantity; shoppingCartItem.Item.UpdatedOnUtc = DateTime.UtcNow; _customerService.UpdateCustomer(customer); //event notification _eventPublisher.EntityUpdated(shoppingCartItem.Item); } } else { //new shopping cart item warnings.AddRange( GetShoppingCartItemWarnings(customer, shoppingCartType, product, storeId, selectedAttributes, customerEnteredPrice, quantity, automaticallyAddRequiredProductsIfEnabled, bundleItem: bundleItem) ); if (warnings.Count == 0) { //maximum items validation switch (shoppingCartType) { case ShoppingCartType.ShoppingCart: if (cart.Count >= _shoppingCartSettings.MaximumShoppingCartItems) { warnings.Add(_localizationService.GetResource("ShoppingCart.MaximumShoppingCartItems")); return warnings; } break; case ShoppingCartType.Wishlist: if (cart.Count >= _shoppingCartSettings.MaximumWishlistItems) { warnings.Add(_localizationService.GetResource("ShoppingCart.MaximumWishlistItems")); return warnings; } break; default: break; } DateTime now = DateTime.UtcNow; var cartItem = new ShoppingCartItem() { ShoppingCartType = shoppingCartType, StoreId = storeId, Product = product, AttributesXml = selectedAttributes, CustomerEnteredPrice = customerEnteredPrice, Quantity = quantity, CreatedOnUtc = now, UpdatedOnUtc = now, ParentItemId = parentItemId }; if (bundleItem != null) cartItem.BundleItemId = bundleItem.Id; customer.ShoppingCartItems.Add(cartItem); _customerService.UpdateCustomer(customer); shoppingCartItemId = cartItem.Id; //event notification _eventPublisher.EntityInserted(cartItem); } } return warnings; }
public static ShoppingCart GetShoppingCart(ShoppingCartType shoppingCartType) { return GetShoppingCart(shoppingCartType, CustomerSession.CustomerId); }
/// <summary> /// Validates shopping cart item attributes /// </summary> /// <param name="customer">The customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="quantity">Quantity</param> /// <param name="bundleItem">Product bundle item</param> /// <returns>Warnings</returns> public virtual IList<string> GetShoppingCartItemAttributeWarnings(Customer customer, ShoppingCartType shoppingCartType, Product product, string selectedAttributes, int quantity = 1, ProductBundleItem bundleItem = null) { if (product == null) throw new ArgumentNullException("product"); var warnings = new List<string>(); if (bundleItem != null && !bundleItem.BundleProduct.BundlePerItemPricing) return warnings; // customer cannot select anything... selectedAttribute is always empty //selected attributes var pva1Collection = _productAttributeParser.ParseProductVariantAttributes(selectedAttributes); foreach (var pva1 in pva1Collection) { var pv1 = pva1.Product; if (pv1 != null) { if (pv1.Id != product.Id) { warnings.Add("Attribute error"); } } else { warnings.Add("Attribute error"); return warnings; } } //existing product attributes var pva2Collection = product.ProductVariantAttributes; foreach (var pva2 in pva2Collection) { if (pva2.IsRequired) { bool found = false; //selected product attributes foreach (var pva1 in pva1Collection) { if (pva1.Id == pva2.Id) { var pvaValuesStr = _productAttributeParser.ParseValues(selectedAttributes, pva1.Id); foreach (string str1 in pvaValuesStr) { if (!String.IsNullOrEmpty(str1.Trim())) { found = true; break; } } } } if (!found && bundleItem != null && bundleItem.FilterAttributes && !bundleItem.AttributeFilters.Exists(x => x.AttributeId == pva2.ProductAttributeId)) { found = true; // attribute is filtered out on bundle item level... it cannot be selected by customer } if (!found) { if (pva2.TextPrompt.HasValue()) warnings.Add(pva2.TextPrompt); else warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.SelectAttribute"), pva2.ProductAttribute.GetLocalized(a => a.Name))); } } } if (warnings.Count == 0) { var pvaValues = _productAttributeParser.ParseProductVariantAttributeValues(selectedAttributes); foreach (var pvaValue in pvaValues) { if (pvaValue.ValueType == ProductVariantAttributeValueType.ProductLinkage) { var linkedProduct = _productService.GetProductById(pvaValue.LinkedProductId); if (linkedProduct != null) { var linkageWarnings = GetShoppingCartItemWarnings(customer, shoppingCartType, linkedProduct, _storeContext.CurrentStore.Id, "", decimal.Zero, quantity * pvaValue.Quantity, false, true, true, true, true); foreach (var linkageWarning in linkageWarnings) { string msg = _localizationService.GetResource("ShoppingCart.ProductLinkageAttributeWarning").FormatWith( pvaValue.ProductVariantAttribute.ProductAttribute.GetLocalized(a => a.Name), pvaValue.GetLocalized(a => a.Name), linkageWarning); warnings.Add(msg); } } else { string msg = _localizationService.GetResource("ShoppingCart.ProductLinkageProductNotLoading").FormatWith(pvaValue.LinkedProductId); warnings.Add(msg); } } } } return warnings; }
public static List<OrganizedShoppingCartItem> GetCartItems(this Customer customer, ShoppingCartType cartType, int? storeId = null, bool orderById = false) { var rawItems = customer.ShoppingCartItems.Filter(cartType, storeId); if (orderById) rawItems = rawItems.OrderByDescending(x => x.Id); var organizedItems = rawItems.ToList().Organize(); return organizedItems.ToList(); }
/// <summary> /// Validates shopping cart item /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="storeId">Store identifier</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">Customer entered price</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductsIfEnabled">Automatically add required products if enabled</param> /// <param name="getStandardWarnings">A value indicating whether we should validate a product for standard properties</param> /// <param name="getAttributesWarnings">A value indicating whether we should validate product attributes</param> /// <param name="getGiftCardWarnings">A value indicating whether we should validate gift card properties</param> /// <param name="getRequiredProductWarnings">A value indicating whether we should validate required products (products which require other products to be added to the cart)</param> /// <param name="getBundleWarnings">A value indicating whether we should validate bundle and bundle items</param> /// <param name="bundleItem">Product bundle item if bundles should be validated</param> /// <param name="childItems">Child cart items to validate bundle items</param> /// <returns>Warnings</returns> public virtual IList<string> GetShoppingCartItemWarnings(Customer customer, ShoppingCartType shoppingCartType, Product product, int storeId, string selectedAttributes, decimal customerEnteredPrice, int quantity, bool automaticallyAddRequiredProductsIfEnabled, bool getStandardWarnings = true, bool getAttributesWarnings = true, bool getGiftCardWarnings = true, bool getRequiredProductWarnings = true, bool getBundleWarnings = true, ProductBundleItem bundleItem = null, IList<OrganizedShoppingCartItem> childItems = null) { if (product == null) throw new ArgumentNullException("product"); var warnings = new List<string>(); //standard properties if (getStandardWarnings) warnings.AddRange(GetStandardWarnings(customer, shoppingCartType, product, selectedAttributes, customerEnteredPrice, quantity)); //selected attributes if (getAttributesWarnings) warnings.AddRange(GetShoppingCartItemAttributeWarnings(customer, shoppingCartType, product, selectedAttributes, quantity, bundleItem)); //gift cards if (getGiftCardWarnings) warnings.AddRange(GetShoppingCartItemGiftCardWarnings(shoppingCartType, product, selectedAttributes)); //required products if (getRequiredProductWarnings) warnings.AddRange(GetRequiredProductWarnings(customer, shoppingCartType, product, storeId, automaticallyAddRequiredProductsIfEnabled)); // bundle and bundle item warnings if (getBundleWarnings) { if (bundleItem != null) warnings.AddRange(GetBundleItemWarnings(bundleItem)); if (childItems != null) warnings.AddRange(GetBundleItemWarnings(childItems)); } return warnings; }
/// <summary> /// Finds a shopping cart item in the cart /// </summary> /// <param name="shoppingCart">Shopping cart</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="customerEnteredPrice">Price entered by a customer</param> /// <param name="rentalStartDate">Rental start date</param> /// <param name="rentalEndDate">Rental end date</param> /// <returns>Found shopping cart item</returns> public virtual ShoppingCartItem FindShoppingCartItemInTheCart(IList<ShoppingCartItem> shoppingCart, ShoppingCartType shoppingCartType, Product product, string attributesXml = "", decimal customerEnteredPrice = decimal.Zero, DateTime? rentalStartDate = null, DateTime? rentalEndDate = null) { if (shoppingCart == null) throw new ArgumentNullException("shoppingCart"); if (product == null) throw new ArgumentNullException("product"); foreach (var sci in shoppingCart.Where(a => a.ShoppingCartType == shoppingCartType)) { if (sci.ProductId == product.ID) { //attributes bool attributesEqual = _productAttributeParser.AreProductAttributesEqual(sci.AttributesXml, attributesXml, false); //gift cards bool giftCardInfoSame = true; if (sci.Product.IsGiftCard) { string giftCardRecipientName1; string giftCardRecipientEmail1; string giftCardSenderName1; string giftCardSenderEmail1; string giftCardMessage1; _productAttributeParser.GetGiftCardAttribute(attributesXml, out giftCardRecipientName1, out giftCardRecipientEmail1, out giftCardSenderName1, out giftCardSenderEmail1, out giftCardMessage1); string giftCardRecipientName2; string giftCardRecipientEmail2; string giftCardSenderName2; string giftCardSenderEmail2; string giftCardMessage2; _productAttributeParser.GetGiftCardAttribute(sci.AttributesXml, out giftCardRecipientName2, out giftCardRecipientEmail2, out giftCardSenderName2, out giftCardSenderEmail2, out giftCardMessage2); if (giftCardRecipientName1.ToLowerInvariant() != giftCardRecipientName2.ToLowerInvariant() || giftCardSenderName1.ToLowerInvariant() != giftCardSenderName2.ToLowerInvariant()) giftCardInfoSame = false; } //price is the same (for products which require customers to enter a price) bool customerEnteredPricesEqual = true; if (sci.Product.CustomerEntersPrice) customerEnteredPricesEqual = Math.Round(sci.CustomerEnteredPrice, 2) == Math.Round(customerEnteredPrice, 2); //rental products bool rentalInfoEqual = true; if (sci.Product.IsRental) { rentalInfoEqual = sci.RentalStartDateUtc == rentalStartDate && sci.RentalEndDateUtc == rentalEndDate; } //found? if (attributesEqual && giftCardInfoSame && customerEnteredPricesEqual && rentalInfoEqual) return sci; } } return null; }
/// <summary> /// Add a product variant to shopping cart /// </summary> /// <param name="customer">Customer</param> /// <param name="productVariant">Product variant</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">The price enter by a customer</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param> /// <returns>Warnings</returns> public virtual IList<string> AddToCart(Customer customer, ProductVariant productVariant, ShoppingCartType shoppingCartType, string selectedAttributes, decimal customerEnteredPrice, int quantity, bool automaticallyAddRequiredProductVariantsIfEnabled) { if (customer == null) throw new ArgumentNullException("customer"); if (productVariant == null) throw new ArgumentNullException("productVariant"); var warnings = new List<string>(); if (shoppingCartType == ShoppingCartType.ShoppingCart && !_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart, customer)) { warnings.Add("Shopping cart is disabled"); return warnings; } if (shoppingCartType == ShoppingCartType.Wishlist && !_permissionService.Authorize(StandardPermissionProvider.EnableWishlist, customer)) { warnings.Add("Wishlist is disabled"); return warnings; } if (quantity <= 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive")); return warnings; } //reset checkout info _customerService.ResetCheckoutData(customer); var cart = customer.ShoppingCartItems.Where(sci=>sci.ShoppingCartType == shoppingCartType).ToList(); var shoppingCartItem = FindShoppingCartItemInTheCart(cart, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice); if (shoppingCartItem != null) { //update existing shopping cart item int newQuantity = shoppingCartItem.Quantity + quantity; warnings.AddRange(GetShoppingCartItemWarnings(customer, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice, newQuantity, automaticallyAddRequiredProductVariantsIfEnabled)); if (warnings.Count == 0) { shoppingCartItem.AttributesXml = selectedAttributes; shoppingCartItem.Quantity = newQuantity; shoppingCartItem.UpdatedOnUtc = DateTime.UtcNow; _customerService.UpdateCustomer(customer); //event notification _eventPublisher.EntityUpdated(shoppingCartItem); } } else { //new shopping cart item warnings.AddRange(GetShoppingCartItemWarnings(customer, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice, quantity, automaticallyAddRequiredProductVariantsIfEnabled)); if (warnings.Count == 0) { //maximum items validation switch (shoppingCartType) { case ShoppingCartType.ShoppingCart: { if (cart.Count >= _shoppingCartSettings.MaximumShoppingCartItems) return warnings; } break; case ShoppingCartType.Wishlist: { if (cart.Count >= _shoppingCartSettings.MaximumWishlistItems) return warnings; } break; default: break; } DateTime now = DateTime.UtcNow; shoppingCartItem = new ShoppingCartItem() { ShoppingCartType = shoppingCartType, ProductVariant = productVariant, AttributesXml = selectedAttributes, CustomerEnteredPrice = customerEnteredPrice, Quantity = quantity, CreatedOnUtc = now, UpdatedOnUtc = now }; customer.ShoppingCartItems.Add(shoppingCartItem); _customerService.UpdateCustomer(customer); //event notification _eventPublisher.EntityInserted(shoppingCartItem); } } return warnings; }
public static ShoppingCartItem GetExistsShoppingCartItem(Guid customerId, int offerId, string attributesXml, ShoppingCartType shoppingCartType) { return SQLDataAccess.ExecuteReadOne<ShoppingCartItem>(" SELECT * FROM [Catalog].[ShoppingCart] " + " WHERE [CustomerId] = @CustomerId AND " + " [OfferId] = @OfferId AND " + " [ShoppingCartType] = @ShoppingCartType AND " + " [AttributesXml] = @AttributesXml", CommandType.Text, (reader) => new ShoppingCartItem { ShoppingCartItemId = SQLDataHelper.GetInt(reader, "ShoppingCartItemId"), ShoppingCartType = (ShoppingCartType)SQLDataHelper.GetInt(reader, "ShoppingCartType"), OfferId = SQLDataHelper.GetInt(reader, "OfferID"), CustomerId = SQLDataHelper.GetGuid(reader, "CustomerId"), AttributesXml = SQLDataHelper.GetString(reader, "AttributesXml"), Amount = SQLDataHelper.GetInt(reader, "Amount"), CreatedOn = SQLDataHelper.GetDateTime(reader, "CreatedOn"), UpdatedOn = SQLDataHelper.GetDateTime(reader, "UpdatedOn"), DesirePrice = SQLDataHelper.GetNullableFloat(reader, "DesirePrice"), }, new SqlParameter { ParameterName = "@CustomerId", Value = customerId }, new SqlParameter { ParameterName = "@OfferId", Value = offerId }, new SqlParameter { ParameterName = "@AttributesXml", Value = attributesXml ?? String.Empty }, new SqlParameter { ParameterName = "@ShoppingCartType", Value = (int)shoppingCartType } ); }
/// <summary> /// Gets all customers /// </summary> /// <param name="createdFromUtc">Created date from (UTC); null to load all records</param> /// <param name="createdToUtc">Created date to (UTC); null to load all records</param> /// <param name="affiliateId">Affiliate identifier</param> /// <param name="vendorId">Vendor identifier</param> /// <param name="customerRoleIds">A list of customer role identifiers to filter by (at least one match); pass null or empty list in order to load all customers; </param> /// <param name="email">Email; null to load all customers</param> /// <param name="username">Username; null to load all customers</param> /// <param name="firstName">First name; null to load all customers</param> /// <param name="lastName">Last name; null to load all customers</param> /// <param name="dayOfBirth">Day of birth; 0 to load all customers</param> /// <param name="monthOfBirth">Month of birth; 0 to load all customers</param> /// <param name="company">Company; null to load all customers</param> /// <param name="phone">Phone; null to load all customers</param> /// <param name="zipPostalCode">Phone; null to load all customers</param> /// <param name="loadOnlyWithShoppingCart">Value indicating whether to load customers only with shopping cart</param> /// <param name="sct">Value indicating what shopping cart type to filter; userd when 'loadOnlyWithShoppingCart' param is 'true'</param> /// <param name="pageIndex">Page index</param> /// <param name="pageSize">Page size</param> /// <returns>Customers</returns> public virtual IPagedList<Customer> GetAllCustomers(DateTime? createdFromUtc = null, DateTime? createdToUtc = null, int affiliateId = 0, int vendorId = 0, int[] customerRoleIds = null, string email = null, string username = null, string firstName = null, string lastName = null, int dayOfBirth = 0, int monthOfBirth = 0, string company = null, string phone = null, string zipPostalCode = null, bool loadOnlyWithShoppingCart = false, ShoppingCartType? sct = null, int pageIndex = 0, int pageSize = 2147483647) { var query = _customerRepository.Table; if (createdFromUtc.HasValue) query = query.Where(c => createdFromUtc.Value <= c.CreatedOnUtc); if (createdToUtc.HasValue) query = query.Where(c => createdToUtc.Value >= c.CreatedOnUtc); if (affiliateId > 0) query = query.Where(c => affiliateId == c.AffiliateId); if (vendorId > 0) query = query.Where(c => vendorId == c.VendorId); query = query.Where(c => !c.Deleted); if (customerRoleIds != null && customerRoleIds.Length > 0) query = query.Where(c => c.CustomerRoles.Any(x => customerRoleIds.Contains(x.Id))); if (!String.IsNullOrWhiteSpace(email)) query = query.Where(c => c.Email!=null && c.Email.ToLower().Contains(email.ToLower())); if (!String.IsNullOrWhiteSpace(username)) query = query.Where(c => c.Username!=null && c.Username.ToLower().Contains(username.ToLower())); if (!String.IsNullOrWhiteSpace(firstName)) { query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.FirstName && y.Value!=null && y.Value.ToLower().Contains(firstName.ToLower()))); } if (!String.IsNullOrWhiteSpace(lastName)) { query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.LastName && y.Value != null && y.Value.ToLower().Contains(lastName.ToLower()))); } //date of birth is stored as a string into database. //we also know that date of birth is stored in the following format YYYY-MM-DD (for example, 1983-02-18). //so let's search it as a string if (dayOfBirth > 0 && monthOfBirth > 0) { //both are specified string dateOfBirthStr = monthOfBirth.ToString("00", CultureInfo.InvariantCulture) + "-" + dayOfBirth.ToString("00", CultureInfo.InvariantCulture); query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.DateOfBirth && y.Value != null && y.Value.ToLower().Contains(dateOfBirthStr.ToLower()))); } else if (dayOfBirth > 0) { //only day is specified string dateOfBirthStr = dayOfBirth.ToString("00", CultureInfo.InvariantCulture); query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.DateOfBirth && y.Value != null && y.Value.ToLower().Contains(dateOfBirthStr.ToLower()))); } else if (monthOfBirth > 0) { //only month is specified string dateOfBirthStr = "-" + monthOfBirth.ToString("00", CultureInfo.InvariantCulture) + "-"; query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.DateOfBirth && y.Value != null && y.Value.ToLower().Contains(dateOfBirthStr.ToLower()))); } //search by company if (!String.IsNullOrWhiteSpace(company)) { query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.Company && y.Value != null && y.Value.ToLower().Contains(company.ToLower()))); } //search by phone if (!String.IsNullOrWhiteSpace(phone)) { query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.Phone && y.Value != null && y.Value.ToLower().Contains(phone.ToLower()))); } //search by zip if (!String.IsNullOrWhiteSpace(zipPostalCode)) { query = query.Where(x => x.GenericAttributes.Any(y => y.Key == SystemCustomerAttributeNames.ZipPostalCode && y.Value != null && y.Value.ToLower().Contains(zipPostalCode.ToLower()))); } if (loadOnlyWithShoppingCart) { int? sctId = null; if (sct.HasValue) sctId = (int)sct.Value; query = sct.HasValue ? query.Where(c => c.ShoppingCartItems.Any(x => x.ShoppingCartTypeId == sctId)) : query.Where(c => c.ShoppingCartItems.Any()); } query = query.OrderByDescending(c => c.CreatedOnUtc); var customers = new PagedList<Customer>(query, pageIndex, pageSize); return customers; }
public static ShoppingCart GetShoppingCart(ShoppingCartType shoppingCartType, Guid customerId) { var templist = SQLDataAccess.ExecuteReadList ("SELECT * FROM Catalog.ShoppingCart WHERE ShoppingCartType = @ShoppingCartType and CustomerId = @CustomerId", CommandType.Text, GetFromReader, new SqlParameter { ParameterName = "@ShoppingCartType", Value = (int)shoppingCartType }, new SqlParameter { ParameterName = "@CustomerId", Value = customerId } ); var shoppingCart = new ShoppingCart(); shoppingCart.AddRange(templist); return shoppingCart; }
public virtual IList<string> Copy(OrganizedShoppingCartItem sci, Customer customer, ShoppingCartType cartType, int storeId, bool addRequiredProductsIfEnabled) { if (customer == null) throw new ArgumentNullException("customer"); if (sci == null) throw new ArgumentNullException("item"); int parentItemId, childItemId; var warnings = AddToCart(customer, sci.Item.Product, cartType, storeId, sci.Item.AttributesXml, sci.Item.CustomerEnteredPrice, sci.Item.Quantity, addRequiredProductsIfEnabled, out parentItemId); if (warnings.Count == 0 && parentItemId != 0 && sci.ChildItems != null) { foreach (var childItem in sci.ChildItems) { AddToCart(customer, childItem.Item.Product, cartType, storeId, childItem.Item.AttributesXml, childItem.Item.CustomerEnteredPrice, childItem.Item.Quantity, false, out childItemId, parentItemId, childItem.Item.BundleItem); } } return warnings; }
public static void ClearShoppingCart(ShoppingCartType shoppingCartType, Guid customerId) { SQLDataAccess.ExecuteNonQuery ("DELETE FROM Catalog.ShoppingCart WHERE ShoppingCartType = @ShoppingCartType and CustomerId = @CustomerId", CommandType.Text, new SqlParameter { ParameterName = "@ShoppingCartType", Value = (int)shoppingCartType }, new SqlParameter { ParameterName = "@CustomerId", Value = customerId } ); }
/// <summary> /// Gets all customers /// </summary> /// <param name="registrationFrom">Customer registration from; null to load all customers</param> /// <param name="registrationTo">Customer registration to; null to load all customers</param> /// <param name="customerRoleIds">A list of customer role identifiers to filter by (at least one match); pass null or empty list in order to load all customers; </param> /// <param name="email">Email; null to load all customers</param> /// <param name="username">Username; null to load all customers</param> /// <param name="firstName">First name; null to load all customers</param> /// <param name="lastName">Last name; null to load all customers</param> /// <param name="dayOfBirth">Day of birth; 0 to load all customers</param> /// <param name="monthOfBirth">Month of birth; 0 to load all customers</param> /// <param name="company">Company; null to load all customers</param> /// <param name="phone">Phone; null to load all customers</param> /// <param name="zipPostalCode">Phone; null to load all customers</param> /// <param name="loadOnlyWithShoppingCart">Value indicating whther to load customers only with shopping cart</param> /// <param name="sct">Value indicating what shopping cart type to filter; userd when 'loadOnlyWithShoppingCart' param is 'true'</param> /// <param name="pageIndex">Page index</param> /// <param name="pageSize">Page size</param> /// <returns>Customer collection</returns> public virtual IPagedList<Customer> GetAllCustomers(DateTime? registrationFrom, DateTime? registrationTo, int[] customerRoleIds, string email, string username, string firstName, string lastName, int dayOfBirth, int monthOfBirth, string company, string phone, string zipPostalCode, bool loadOnlyWithShoppingCart, ShoppingCartType? sct, int pageIndex, int pageSize) { var query = _customerRepository.Table; if (registrationFrom.HasValue) query = query.Where(c => registrationFrom.Value <= c.CreatedOnUtc); if (registrationTo.HasValue) query = query.Where(c => registrationTo.Value >= c.CreatedOnUtc); query = query.Where(c => !c.Deleted); if (customerRoleIds != null && customerRoleIds.Length > 0) query = query.Where(c => c.CustomerRoles.Select(cr => cr.Id).Intersect(customerRoleIds).Count() > 0); if (!String.IsNullOrWhiteSpace(email)) query = query.Where(c => c.Email.Contains(email)); if (!String.IsNullOrWhiteSpace(username)) query = query.Where(c => c.Username.Contains(username)); if (!String.IsNullOrWhiteSpace(firstName)) { query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.FirstName && z.Attribute.Value.Contains(firstName))) .Select(z => z.Customer); } if (!String.IsNullOrWhiteSpace(lastName)) { query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.LastName && z.Attribute.Value.Contains(lastName))) .Select(z => z.Customer); } //date of birth is stored as a string into database. //we also know that date of birth is stored in the following format YYYY-MM-DD (for example, 1983-02-18). //so let's search it as a string if (dayOfBirth > 0 && monthOfBirth > 0) { //both are specified string dateOfBirthStr = monthOfBirth.ToString("00", CultureInfo.InvariantCulture) + "-" + dayOfBirth.ToString("00", CultureInfo.InvariantCulture); //EndsWith is not supported by SQL Server Compact //so let's use the following workaround http://social.msdn.microsoft.com/Forums/is/sqlce/thread/0f810be1-2132-4c59-b9ae-8f7013c0cc00 //we also cannot use Length function in SQL Server Compact (not supported in this context) //z.Attribute.Value.Length - dateOfBirthStr.Length = 5 //dateOfBirthStr.Length = 5 query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.DateOfBirth && z.Attribute.Value.Substring(5, 5) == dateOfBirthStr)) .Select(z => z.Customer); } else if (dayOfBirth > 0) { //only day is specified string dateOfBirthStr = dayOfBirth.ToString("00", CultureInfo.InvariantCulture); //EndsWith is not supported by SQL Server Compact //so let's use the following workaround http://social.msdn.microsoft.com/Forums/is/sqlce/thread/0f810be1-2132-4c59-b9ae-8f7013c0cc00 //we also cannot use Length function in SQL Server Compact (not supported in this context) //z.Attribute.Value.Length - dateOfBirthStr.Length = 8 //dateOfBirthStr.Length = 2 query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.DateOfBirth && z.Attribute.Value.Substring(8, 2) == dateOfBirthStr)) .Select(z => z.Customer); } else if (monthOfBirth > 0) { //only month is specified string dateOfBirthStr = "-" + monthOfBirth.ToString("00", CultureInfo.InvariantCulture) + "-"; query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.DateOfBirth && z.Attribute.Value.Contains(dateOfBirthStr))) .Select(z => z.Customer); } //search by company if (!String.IsNullOrWhiteSpace(company)) { query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.Company && z.Attribute.Value.Contains(company))) .Select(z => z.Customer); } //search by phone if (!String.IsNullOrWhiteSpace(phone)) { query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.Phone && z.Attribute.Value.Contains(phone))) .Select(z => z.Customer); } //search by zip if (!String.IsNullOrWhiteSpace(zipPostalCode)) { query = query .Join(_gaRepository.Table, x => x.Id, y => y.EntityId, (x, y) => new { Customer = x, Attribute = y }) .Where((z => z.Attribute.KeyGroup == "Customer" && z.Attribute.Key == SystemCustomerAttributeNames.ZipPostalCode && z.Attribute.Value.Contains(zipPostalCode))) .Select(z => z.Customer); } if (loadOnlyWithShoppingCart) { int? sctId = null; if (sct.HasValue) sctId = (int)sct.Value; query = sct.HasValue ? query.Where(c => c.ShoppingCartItems.Where(x => x.ShoppingCartTypeId == sctId).Count() > 0) : query.Where(c => c.ShoppingCartItems.Count() > 0); } query = query.OrderByDescending(c => c.CreatedOnUtc); var customers = new PagedList<Customer>(query, pageIndex, pageSize); return customers; }
/// <summary> /// Finds a shopping cart item in the cart /// </summary> /// <param name="shoppingCart">Shopping cart</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">Price entered by a customer</param> /// <returns>Found shopping cart item</returns> public virtual ShoppingCartItem FindShoppingCartItemInTheCart(IList<ShoppingCartItem> shoppingCart, ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes = "", decimal customerEnteredPrice = decimal.Zero) { if (shoppingCart == null) throw new ArgumentNullException("shoppingCart"); if (productVariant == null) throw new ArgumentNullException("productVariant"); foreach (var sci in shoppingCart.Where(a => a.ShoppingCartType == shoppingCartType)) { if (sci.ProductVariantId == productVariant.Id) { //attributes bool attributesEqual = _productAttributeParser.AreProductAttributesEqual(sci.AttributesXml, selectedAttributes); //gift cards bool giftCardInfoSame = true; if (sci.ProductVariant.IsGiftCard) { string giftCardRecipientName1 = string.Empty; string giftCardRecipientEmail1 = string.Empty; string giftCardSenderName1 = string.Empty; string giftCardSenderEmail1 = string.Empty; string giftCardMessage1 = string.Empty; _productAttributeParser.GetGiftCardAttribute(selectedAttributes, out giftCardRecipientName1, out giftCardRecipientEmail1, out giftCardSenderName1, out giftCardSenderEmail1, out giftCardMessage1); string giftCardRecipientName2 = string.Empty; string giftCardRecipientEmail2 = string.Empty; string giftCardSenderName2 = string.Empty; string giftCardSenderEmail2 = string.Empty; string giftCardMessage2 = string.Empty; _productAttributeParser.GetGiftCardAttribute(sci.AttributesXml, out giftCardRecipientName2, out giftCardRecipientEmail2, out giftCardSenderName2, out giftCardSenderEmail2, out giftCardMessage2); if (giftCardRecipientName1.ToLowerInvariant() != giftCardRecipientName2.ToLowerInvariant() || giftCardSenderName1.ToLowerInvariant() != giftCardSenderName2.ToLowerInvariant()) giftCardInfoSame = false; } //price is the same (for products which require customers to enter a price) bool customerEnteredPricesEqual = true; if (sci.ProductVariant.CustomerEntersPrice) customerEnteredPricesEqual = Math.Round(sci.CustomerEnteredPrice, 2) == Math.Round(customerEnteredPrice, 2); //found? if (attributesEqual && giftCardInfoSame && customerEnteredPricesEqual) return sci; } } return null; }
public virtual void AddToCart(List<string> warnings, Product product, NameValueCollection form, ShoppingCartType cartType, decimal customerEnteredPrice, int quantity, bool addRequiredProducts, int? parentCartItemId = null, ProductBundleItem bundleItem = null) { int newCartItemId; string selectedAttributes = ""; int bundleItemId = (bundleItem == null ? 0 : bundleItem.Id); var attributes = _productAttributeService.GetProductVariantAttributesByProductId(product.Id); selectedAttributes = form.CreateSelectedAttributesXml(product.Id, attributes, _productAttributeParser, _localizationService, _downloadService, _catalogSettings, null, warnings, true, bundleItemId); if (product.ProductType == ProductType.BundledProduct && selectedAttributes.HasValue()) { warnings.Add(_localizationService.GetResource("ShoppingCart.Bundle.NoAttributes")); return; } if (product.IsGiftCard) { selectedAttributes = form.AddGiftCardAttribute(selectedAttributes, product.Id, _productAttributeParser, bundleItemId); } warnings.AddRange( AddToCart(_workContext.CurrentCustomer, product, cartType, _storeContext.CurrentStore.Id, selectedAttributes, customerEnteredPrice, quantity, addRequiredProducts, out newCartItemId, parentCartItemId, bundleItem) ); if (product.ProductType == ProductType.BundledProduct && warnings.Count <= 0 && newCartItemId != 0 && bundleItem == null) { foreach (var item in _productService.GetBundleItems(product.Id).Select(x => x.Item)) { AddToCart(warnings, item.Product, form, cartType, decimal.Zero, item.Quantity, false, newCartItemId, item); } if (warnings.Count > 0) DeleteShoppingCartItem(newCartItemId); } }
/// <summary> /// Validates shopping cart item attributes /// </summary> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <returns>Warnings</returns> public virtual IList<string> GetShoppingCartItemAttributeWarnings(ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes) { if (productVariant == null) throw new ArgumentNullException("productVariant"); var warnings = new List<string>(); //selected attributes var pva1Collection = _productAttributeParser.ParseProductVariantAttributes(selectedAttributes); foreach (var pva1 in pva1Collection) { var pv1 = pva1.ProductVariant; if (pv1 != null) { if (pv1.Id != productVariant.Id) { warnings.Add("Attribute error"); } } else { warnings.Add("Attribute error"); return warnings; } } //existing product attributes var pva2Collection = productVariant.ProductVariantAttributes; foreach (var pva2 in pva2Collection) { if (pva2.IsRequired) { bool found = false; //selected product attributes foreach (var pva1 in pva1Collection) { if (pva1.Id == pva2.Id) { var pvaValuesStr = _productAttributeParser.ParseValues(selectedAttributes, pva1.Id); foreach (string str1 in pvaValuesStr) { if (!String.IsNullOrEmpty(str1.Trim())) { found = true; break; } } } } //if not found if (!found) { if (!string.IsNullOrEmpty(pva2.TextPrompt)) { warnings.Add(pva2.TextPrompt); } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.SelectAttribute"), pva2.ProductAttribute.GetLocalized(a => a.Name))); } } } } return warnings; }
/// <summary> /// Add a product to shopping cart /// </summary> /// <param name="customer">Customer</param> /// <param name="product">Product</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="storeId">Store identifier</param> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="customerEnteredPrice">The price enter by a customer</param> /// <param name="rentalStartDate">Rental start date</param> /// <param name="rentalEndDate">Rental end date</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductsIfEnabled">Automatically add required products if enabled</param> /// <returns>Warnings</returns> public virtual IList<string> AddToCart(Customer customer, Product product, ShoppingCartType shoppingCartType, int storeId, string attributesXml = null, decimal customerEnteredPrice = decimal.Zero, DateTime? rentalStartDate = null, DateTime? rentalEndDate = null, int quantity = 1, bool automaticallyAddRequiredProductsIfEnabled = true) { if (customer == null) throw new ArgumentNullException("customer"); if (product == null) throw new ArgumentNullException("product"); var warnings = new List<string>(); if (shoppingCartType == ShoppingCartType.ShoppingCart && !_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart, customer)) { warnings.Add("Shopping cart is disabled"); return warnings; } if (shoppingCartType == ShoppingCartType.Wishlist && !_permissionService.Authorize(StandardPermissionProvider.EnableWishlist, customer)) { warnings.Add("Wishlist is disabled"); return warnings; } if (customer.IsSearchEngineAccount()) { warnings.Add("Search engine can't add to cart"); return warnings; } if (quantity <= 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive")); return warnings; } //reset checkout info _customerService.ResetCheckoutData(customer, storeId); var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartType == shoppingCartType) .LimitPerStore(storeId) .ToList(); var shoppingCartItem = FindShoppingCartItemInTheCart(cart, shoppingCartType, product, attributesXml, customerEnteredPrice, rentalStartDate, rentalEndDate); if (shoppingCartItem != null) { //update existing shopping cart item int newQuantity = shoppingCartItem.Quantity + quantity; warnings.AddRange(GetShoppingCartItemWarnings(customer, shoppingCartType, product, storeId, attributesXml, customerEnteredPrice, rentalStartDate, rentalEndDate, newQuantity, automaticallyAddRequiredProductsIfEnabled)); if (warnings.Count == 0) { shoppingCartItem.AttributesXml = attributesXml; shoppingCartItem.Quantity = newQuantity; shoppingCartItem.UpdatedOnUtc = DateTime.UtcNow; _customerService.UpdateCustomer(customer); //event notification _eventPublisher.EntityUpdated(shoppingCartItem); } } else { //new shopping cart item warnings.AddRange(GetShoppingCartItemWarnings(customer, shoppingCartType, product, storeId, attributesXml, customerEnteredPrice, rentalStartDate, rentalEndDate, quantity, automaticallyAddRequiredProductsIfEnabled)); if (warnings.Count == 0) { //maximum items validation switch (shoppingCartType) { case ShoppingCartType.ShoppingCart: { if (cart.Count >= _shoppingCartSettings.MaximumShoppingCartItems) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumShoppingCartItems"), _shoppingCartSettings.MaximumShoppingCartItems)); return warnings; } } break; case ShoppingCartType.Wishlist: { if (cart.Count >= _shoppingCartSettings.MaximumWishlistItems) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumWishlistItems"), _shoppingCartSettings.MaximumWishlistItems)); return warnings; } } break; default: break; } DateTime now = DateTime.UtcNow; shoppingCartItem = new ShoppingCartItem { ShoppingCartType = shoppingCartType, StoreId = storeId, Product = product, AttributesXml = attributesXml, CustomerEnteredPrice = customerEnteredPrice, Quantity = quantity, RentalStartDateUtc = rentalStartDate, RentalEndDateUtc = rentalEndDate, CreatedOnUtc = now, UpdatedOnUtc = now }; customer.ShoppingCartItems.Add(shoppingCartItem); _customerService.UpdateCustomer(customer); //updated "HasShoppingCartItems" property used for performance optimization customer.HasShoppingCartItems = customer.ShoppingCartItems.Count > 0; _customerService.UpdateCustomer(customer); //event notification _eventPublisher.EntityInserted(shoppingCartItem); } } return warnings; }
/// <summary> /// Validates shopping cart item /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">Customer entered price</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param> /// <param name="getStandardWarnings">A value indicating whether we should validate a product variant for standard properties</param> /// <param name="getAttributesWarnings">A value indicating whether we should validate product attributes</param> /// <param name="getGiftCardWarnings">A value indicating whether we should validate gift card properties</param> /// <param name="getRequiredProductVariantWarnings">A value indicating whether we should validate required product variants (product variants which require other variant to be added to the cart)</param> /// <returns>Warnings</returns> public virtual IList<string> GetShoppingCartItemWarnings(Customer customer, ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes, decimal customerEnteredPrice, int quantity, bool automaticallyAddRequiredProductVariantsIfEnabled, bool getStandardWarnings = true, bool getAttributesWarnings = true, bool getGiftCardWarnings = true, bool getRequiredProductVariantWarnings = true) { if (productVariant == null) throw new ArgumentNullException("productVariant"); var warnings = new List<string>(); //standard properties if (getStandardWarnings) warnings.AddRange(GetStandardWarnings(customer, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice, quantity)); //selected attributes if (getAttributesWarnings) warnings.AddRange(GetShoppingCartItemAttributeWarnings(shoppingCartType, productVariant, selectedAttributes)); //gift cards if (getGiftCardWarnings) warnings.AddRange(GetShoppingCartItemGiftCardWarnings(shoppingCartType, productVariant, selectedAttributes)); //required product variants if (getRequiredProductVariantWarnings) warnings.AddRange(GetRequiredProductVariantWarnings(customer, shoppingCartType, productVariant, automaticallyAddRequiredProductVariantsIfEnabled)); return warnings; }
/// <summary> /// Validates required products (products which require some other products to be added to the cart) /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="storeId">Store identifier</param> /// <param name="automaticallyAddRequiredProductsIfEnabled">Automatically add required products if enabled</param> /// <returns>Warnings</returns> public virtual IList<string> GetRequiredProductWarnings(Customer customer, ShoppingCartType shoppingCartType, Product product, int storeId, bool automaticallyAddRequiredProductsIfEnabled) { if (customer == null) throw new ArgumentNullException("customer"); if (product == null) throw new ArgumentNullException("product"); var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartType == shoppingCartType) .LimitPerStore(storeId) .ToList(); var warnings = new List<string>(); if (product.RequireOtherProducts) { var requiredProducts = new List<Product>(); foreach (var id in product.ParseRequiredProductIds()) { var rp = _productService.GetProductById(id); if (rp != null) requiredProducts.Add(rp); } foreach (var rp in requiredProducts) { //ensure that product is in the cart bool alreadyInTheCart = false; foreach (var sci in cart) { if (sci.ProductId == rp.ID) { alreadyInTheCart = true; break; } } //not in the cart if (!alreadyInTheCart) { if (product.AutomaticallyAddRequiredProducts) { //add to cart (if possible) if (automaticallyAddRequiredProductsIfEnabled) { //pass 'false' for 'automaticallyAddRequiredProductsIfEnabled' to prevent circular references var addToCartWarnings = AddToCart(customer: customer, product: rp, shoppingCartType: shoppingCartType, storeId: storeId, automaticallyAddRequiredProductsIfEnabled: false); if (addToCartWarnings.Count > 0) { //a product wasn't atomatically added for some reasons //don't display specific errors from 'addToCartWarnings' variable //display only generic error warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), rp.GetLocalized(x => x.Name))); } } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), rp.GetLocalized(x => x.Name))); } } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), rp.GetLocalized(x => x.Name))); } } } } return warnings; }
/// <summary> /// Gets the shopping cart unit price (one item) /// </summary> /// <param name="product">Product</param> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="quantity">Quantity</param> /// <param name="attributesXml">Product atrributes (XML format)</param> /// <param name="customerEnteredPrice">Customer entered price (if specified)</param> /// <param name="rentalStartDate">Rental start date (null for not rental products)</param> /// <param name="rentalEndDate">Rental end date (null for not rental products)</param> /// <param name="includeDiscounts">A value indicating whether include discounts or not for price computation</param> /// <param name="discountAmount">Applied discount amount</param> /// <param name="appliedDiscounts">Applied discounts</param> /// <returns>Shopping cart unit price (one item)</returns> public virtual decimal GetUnitPrice(Product product, Customer customer, ShoppingCartType shoppingCartType, int quantity, string attributesXml, decimal customerEnteredPrice, DateTime? rentalStartDate, DateTime? rentalEndDate, bool includeDiscounts, out decimal discountAmount, out List<Discount> appliedDiscounts) { if (product == null) throw new ArgumentNullException("product"); if (customer == null) throw new ArgumentNullException("customer"); discountAmount = decimal.Zero; appliedDiscounts = new List<Discount>(); decimal finalPrice; var combination = _productAttributeParser.FindProductAttributeCombination(product, attributesXml); if (combination != null && combination.OverriddenPrice.HasValue) { finalPrice = GetFinalPrice(product, customer, combination.OverriddenPrice.Value, decimal.Zero, includeDiscounts, quantity, product.IsRental ? rentalStartDate : null, product.IsRental ? rentalEndDate : null, out discountAmount, out appliedDiscounts); } else { //summarize price of all attributes decimal attributesTotalPrice = decimal.Zero; var attributeValues = _productAttributeParser.ParseProductAttributeValues(attributesXml); if (attributeValues != null) { foreach (var attributeValue in attributeValues) { attributesTotalPrice += GetProductAttributeValuePriceAdjustment(attributeValue); } } //get price of a product (with previously calculated price of all attributes) if (product.CustomerEntersPrice) { finalPrice = customerEnteredPrice; } else { int qty; if (_shoppingCartSettings.GroupTierPricesForDistinctShoppingCartItems) { //the same products with distinct product attributes could be stored as distinct "ShoppingCartItem" records //so let's find how many of the current products are in the cart qty = customer.ShoppingCartItems .Where(x => x.ProductId == product.Id) .Where(x => x.ShoppingCartType == shoppingCartType) .Sum(x => x.Quantity); if (qty == 0) { qty = quantity; } } else { qty = quantity; } finalPrice = GetFinalPrice(product, customer, attributesTotalPrice, includeDiscounts, qty, product.IsRental ? rentalStartDate : null, product.IsRental ? rentalEndDate : null, out discountAmount, out appliedDiscounts); } } //rounding if (_shoppingCartSettings.RoundPricesDuringCalculation) finalPrice = RoundingHelper.RoundPrice(finalPrice); return finalPrice; }
/// <summary> /// Validates a product for standard properties /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="product">Product</param> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="customerEnteredPrice">Customer entered price</param> /// <param name="quantity">Quantity</param> /// <returns>Warnings</returns> public virtual IList<string> GetStandardWarnings(Customer customer, ShoppingCartType shoppingCartType, Product product, string attributesXml, decimal customerEnteredPrice, int quantity) { if (customer == null) throw new ArgumentNullException("customer"); if (product == null) throw new ArgumentNullException("product"); var warnings = new List<string>(); //deleted if (product.Deleted) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductDeleted")); return warnings; } //published if (!product.Published) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished")); } //we can add only simple products if (product.ProductType != ProductType.SimpleProduct) { warnings.Add("This is not simple product"); } //ACL if (!_aclService.Authorize(product, customer)) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished")); } //Store mapping if (!_storeMappingService.Authorize(product, _storeContext.CurrentStore.ID)) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished")); } //disabled "add to cart" button if (shoppingCartType == ShoppingCartType.ShoppingCart && product.DisableBuyButton) { warnings.Add(_localizationService.GetResource("ShoppingCart.BuyingDisabled")); } //disabled "add to wishlist" button if (shoppingCartType == ShoppingCartType.Wishlist && product.DisableWishlistButton) { warnings.Add(_localizationService.GetResource("ShoppingCart.WishlistDisabled")); } //call for price if (shoppingCartType == ShoppingCartType.ShoppingCart && product.CallForPrice) { warnings.Add(_localizationService.GetResource("Products.CallForPrice")); } //customer entered price if (product.CustomerEntersPrice) { if (customerEnteredPrice < product.MinimumCustomerEnteredPrice || customerEnteredPrice > product.MaximumCustomerEnteredPrice) { decimal minimumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(product.MinimumCustomerEnteredPrice, _workContext.WorkingCurrency); decimal maximumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(product.MaximumCustomerEnteredPrice, _workContext.WorkingCurrency); warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CustomerEnteredPrice.RangeError"), _priceFormatter.FormatPrice(minimumCustomerEnteredPrice, false, false), _priceFormatter.FormatPrice(maximumCustomerEnteredPrice, false, false))); } } //quantity validation var hasQtyWarnings = false; if (quantity < product.OrderMinimumQuantity) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MinimumQuantity"), product.OrderMinimumQuantity)); hasQtyWarnings = true; } if (quantity > product.OrderMaximumQuantity) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumQuantity"), product.OrderMaximumQuantity)); hasQtyWarnings = true; } var allowedQuantities = product.ParseAllowedQuatities(); if (allowedQuantities.Length > 0 && !allowedQuantities.Contains(quantity)) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.AllowedQuantities"), string.Join(", ", allowedQuantities))); } var validateOutOfStock = shoppingCartType == ShoppingCartType.ShoppingCart || !_shoppingCartSettings.AllowOutOfStockItemsToBeAddedToWishlist; if (validateOutOfStock && !hasQtyWarnings) { switch (product.ManageInventoryMethod) { case ManageInventoryMethod.DontManageStock: { //do nothing } break; case ManageInventoryMethod.ManageStock: { if (product.BackorderMode == BackorderMode.NoBackorders) { int maximumQuantityCanBeAdded = product.GetTotalStockQuantity(); if (maximumQuantityCanBeAdded < quantity) { if (maximumQuantityCanBeAdded <= 0) warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock")); else warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded)); } } } break; case ManageInventoryMethod.ManageStockByAttributes: { var combination = _productAttributeParser.FindProductAttributeCombination(product, attributesXml); if (combination != null) { //combination exists //let's check stock level if (!combination.AllowOutOfStockOrders && combination.StockQuantity < quantity) { int maximumQuantityCanBeAdded = combination.StockQuantity; if (maximumQuantityCanBeAdded <= 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock")); } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded)); } } } else { //combination doesn't exist if (product.AllowAddingOnlyExistingAttributeCombinations) { //maybe, is it better to display something like "No such product/combination" message? warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock")); } } } break; default: break; } } //availability dates bool availableStartDateError = false; if (product.AvailableStartDateTimeUtc.HasValue) { DateTime now = DateTime.UtcNow; DateTime availableStartDateTime = DateTime.SpecifyKind(product.AvailableStartDateTimeUtc.Value, DateTimeKind.Utc); if (availableStartDateTime.CompareTo(now) > 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); availableStartDateError = true; } } if (product.AvailableEndDateTimeUtc.HasValue && !availableStartDateError) { DateTime now = DateTime.UtcNow; DateTime availableEndDateTime = DateTime.SpecifyKind(product.AvailableEndDateTimeUtc.Value, DateTimeKind.Utc); if (availableEndDateTime.CompareTo(now) < 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); } } return warnings; }