public virtual async Task <IActionResult> AddProductCatalog(string productId, int shoppingCartTypeId, int quantity, bool forceredirection = false) { var cartType = (ShoppingCartType)shoppingCartTypeId; var product = await _productService.GetProductById(productId); if (product == null) { //no product found return(Json(new { success = false, message = "No product found with the specified ID" })); } //we can add only simple products and if (product.ProductTypeId != ProductType.SimpleProduct || _shoppingCartSettings.AllowToSelectWarehouse) { return(Json(new { redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName(_workContext.WorkingLanguage.Id) }), })); } //products with "minimum order quantity" more than a specified qty if (product.OrderMinimumQuantity > quantity) { //we cannot add to the cart such products from category pages //it can confuse customers. That's why we redirect customers to the product details page return(Json(new { redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName(_workContext.WorkingLanguage.Id) }), })); } if (product.EnteredPrice) { //cannot be added to the cart (requires a customer to enter price) return(Json(new { redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName(_workContext.WorkingLanguage.Id) }), })); } var allowedQuantities = product.ParseAllowedQuantities(); if (allowedQuantities.Length > 0) { //cannot be added to the cart (requires a customer to select a quantity from dropdownlist) return(Json(new { redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName(_workContext.WorkingLanguage.Id) }), })); } if (product.ProductAttributeMappings.Any()) { //product has some attributes. let a customer see them return(Json(new { redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName(_workContext.WorkingLanguage.Id) }), })); } var customer = _workContext.CurrentCustomer; string warehouseId = product.UseMultipleWarehouses ? _workContext.CurrentStore.DefaultWarehouseId : (string.IsNullOrEmpty(_workContext.CurrentStore.DefaultWarehouseId) ? product.WarehouseId : _workContext.CurrentStore.DefaultWarehouseId); //get standard warnings without attribute validations //first, try to find existing shopping cart item var cart = _shoppingCartService.GetShoppingCart(_workContext.CurrentStore.Id, cartType); var shoppingCartItem = await _shoppingCartService.FindShoppingCartItem(cart, cartType, product.Id, warehouseId); //if we already have the same product in the cart, then use the total quantity to validate var quantityToValidate = shoppingCartItem != null ? shoppingCartItem.Quantity + quantity : quantity; var addToCartWarnings = await _shoppingCartValidator .GetShoppingCartItemWarnings(customer, new ShoppingCartItem() { ShoppingCartTypeId = cartType, StoreId = _workContext.CurrentStore.Id, WarehouseId = warehouseId, Quantity = quantityToValidate }, product, new ShoppingCartValidatorOptions() { GetRequiredProductWarnings = false }); if (addToCartWarnings.Any()) { //cannot be added to the cart return(Json(new { redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName(_workContext.WorkingLanguage.Id) }), })); } //try adding product to the cart (now including product attribute validation, etc) addToCartWarnings = await _shoppingCartService.AddToCart(customer : customer, productId : productId, shoppingCartType : cartType, storeId : _workContext.CurrentStore.Id, warehouseId : warehouseId, quantity : quantity, getRequiredProductWarnings : false); if (addToCartWarnings.Any()) { //cannot be added to the cart //but we do not display attribute and gift voucher warnings here. do it on the product details page return(Json(new { redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName(_workContext.WorkingLanguage.Id) }), })); } var addtoCartModel = await _mediator.Send(new GetAddToCart() { Product = product, Customer = customer, Quantity = quantity, CartType = cartType, Currency = _workContext.WorkingCurrency, Store = _workContext.CurrentStore, Language = _workContext.WorkingLanguage, TaxDisplayType = _workContext.TaxDisplayType, }); //added to the cart/wishlist switch (cartType) { case ShoppingCartType.Wishlist: { //activity log await _customerActivityService.InsertActivity("PublicStore.AddToWishlist", product.Id, _translationService.GetResource("ActivityLog.PublicStore.AddToWishlist"), product.Name); if (_shoppingCartSettings.DisplayWishlistAfterAddingProduct || forceredirection) { //redirect to the wishlist page return(Json(new { redirect = Url.RouteUrl("Wishlist"), })); } //display notification message and update appropriate blocks var qty = _shoppingCartService.GetShoppingCart(_workContext.CurrentStore.Id, ShoppingCartType.Wishlist).Sum(x => x.Quantity); var updatetopwishlistsectionhtml = string.Format(_translationService.GetResource("Wishlist.HeaderQuantity"), qty); return(Json(new { success = true, message = string.Format(_translationService.GetResource("Products.ProductHasBeenAddedToTheWishlist.Link"), Url.RouteUrl("Wishlist")), html = await this.RenderPartialViewToString("_PopupAddToCart", addtoCartModel, true), updatetopwishlistsectionhtml = updatetopwishlistsectionhtml, wishlistqty = qty, model = addtoCartModel })); } case ShoppingCartType.ShoppingCart: default: { //activity log await _customerActivityService.InsertActivity("PublicStore.AddToShoppingCart", product.Id, _translationService.GetResource("ActivityLog.PublicStore.AddToShoppingCart"), product.Name); if (_shoppingCartSettings.DisplayCartAfterAddingProduct || forceredirection) { //redirect to the shopping cart page return(Json(new { redirect = Url.RouteUrl("ShoppingCart"), })); } //display notification message and update appropriate blocks var shoppingCartTypes = new List <ShoppingCartType>(); shoppingCartTypes.Add(ShoppingCartType.ShoppingCart); shoppingCartTypes.Add(ShoppingCartType.Auctions); if (_shoppingCartSettings.AllowOnHoldCart) { shoppingCartTypes.Add(ShoppingCartType.OnHoldCart); } var updatetopcartsectionhtml = string.Format(_translationService.GetResource("ShoppingCart.HeaderQuantity"), _shoppingCartService.GetShoppingCart(_workContext.CurrentStore.Id, shoppingCartTypes.ToArray()) .Sum(x => x.Quantity)); var miniShoppingCartmodel = _shoppingCartSettings.MiniShoppingCartEnabled ? await _mediator.Send(new GetMiniShoppingCart() { Customer = _workContext.CurrentCustomer, Currency = _workContext.WorkingCurrency, Language = _workContext.WorkingLanguage, TaxDisplayType = _workContext.TaxDisplayType, Store = _workContext.CurrentStore }) : null; return(Json(new { success = true, message = string.Format(_translationService.GetResource("Products.ProductHasBeenAddedToTheCart.Link"), Url.RouteUrl("ShoppingCart")), html = await this.RenderPartialViewToString("_PopupAddToCart", addtoCartModel, true), updatetopcartsectionhtml = updatetopcartsectionhtml, sidebarshoppingcartmodel = miniShoppingCartmodel, model = addtoCartModel })); } } }
private async Task PrepareCartItems(ShoppingCartModel model, GetShoppingCart request) { #region Cart items foreach (var sci in request.Cart) { var product = await _productService.GetProductById(sci.ProductId); if (product == null) { continue; } var sename = product.GetSeName(request.Language.Id); var cartItemModel = new ShoppingCartModel.ShoppingCartItemModel { Id = sci.Id, Sku = product.FormatSku(sci.Attributes, _productAttributeParser), IsCart = sci.ShoppingCartTypeId == ShoppingCartType.ShoppingCart, ProductId = product.Id, WarehouseId = sci.WarehouseId, ProductName = product.GetTranslation(x => x.Name, request.Language.Id), ProductSeName = sename, ProductUrl = _linkGenerator.GetUriByRouteValues(_httpContextAccessor.HttpContext, "Product", new { SeName = sename }), Quantity = sci.Quantity, AttributeInfo = await _productAttributeFormatter.FormatAttributes(product, sci.Attributes), }; cartItemModel.AllowItemEditing = _shoppingCartSettings.AllowCartItemEditing && product.ProductTypeId == ProductType.SimpleProduct && (!String.IsNullOrEmpty(cartItemModel.AttributeInfo) || product.IsGiftVoucher) && product.VisibleIndividually; if (product.RequireOtherProducts) { cartItemModel.DisableRemoval = product.RequireOtherProducts && product.ParseRequiredProductIds().Intersect(request.Cart.Select(x => x.ProductId)).Any(); } //warehouse if (!string.IsNullOrEmpty(cartItemModel.WarehouseId)) { cartItemModel.WarehouseName = (await _warehouseService.GetWarehouseById(cartItemModel.WarehouseId))?.Name; } //vendor if (!string.IsNullOrEmpty(product.VendorId)) { var vendor = await _vendorService.GetVendorById(product.VendorId); if (vendor != null) { cartItemModel.VendorId = product.VendorId; cartItemModel.VendorName = vendor.Name; cartItemModel.VendorSeName = vendor.GetSeName(request.Language.Id); } } //allowed quantities var allowedQuantities = product.ParseAllowedQuantities(); foreach (var qty in allowedQuantities) { cartItemModel.AllowedQuantities.Add(new SelectListItem { Text = qty.ToString(), Value = qty.ToString(), Selected = sci.Quantity == qty }); } //recurring info if (product.IsRecurring) { cartItemModel.RecurringInfo = string.Format(_translationService.GetResource("ShoppingCart.RecurringPeriod"), product.RecurringCycleLength, product.RecurringCyclePeriodId.GetTranslationEnum(_translationService, request.Language.Id)); } //reservation info if (product.ProductTypeId == ProductType.Reservation) { if (sci.RentalEndDateUtc == default(DateTime) || sci.RentalEndDateUtc == null) { cartItemModel.ReservationInfo = string.Format(_translationService.GetResource("ShoppingCart.Reservation.StartDate"), sci.RentalStartDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat)); } else { cartItemModel.ReservationInfo = string.Format(_translationService.GetResource("ShoppingCart.Reservation.Date"), sci.RentalStartDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat), sci.RentalEndDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat)); } if (!string.IsNullOrEmpty(sci.Parameter)) { cartItemModel.ReservationInfo += "<br>" + string.Format(_translationService.GetResource("ShoppingCart.Reservation.Option"), sci.Parameter); cartItemModel.Parameter = sci.Parameter; } if (!string.IsNullOrEmpty(sci.Duration)) { cartItemModel.ReservationInfo += "<br>" + string.Format(_translationService.GetResource("ShoppingCart.Reservation.Duration"), sci.Duration); } } if (sci.ShoppingCartTypeId == ShoppingCartType.Auctions) { cartItemModel.DisableRemoval = true; cartItemModel.AuctionInfo = _translationService.GetResource("ShoppingCart.auctionwonon") + " " + _dateTimeService.ConvertToUserTime(product.AvailableEndDateTimeUtc.Value, DateTimeKind.Utc).ToString(); } //unit prices if (product.CallForPrice) { cartItemModel.UnitPrice = _translationService.GetResource("Products.CallForPrice"); cartItemModel.SubTotal = _translationService.GetResource("Products.CallForPrice"); cartItemModel.UnitPriceWithoutDiscount = _translationService.GetResource("Products.CallForPrice"); } else { var unitprices = await _pricingService.GetUnitPrice(sci, product, true); decimal discountAmount = unitprices.discountAmount; List <ApplyDiscount> appliedDiscounts = unitprices.appliedDiscounts; var productprices = await _taxService.GetProductPrice(product, unitprices.unitprice); decimal taxRate = productprices.taxRate; cartItemModel.UnitPriceWithoutDiscountValue = (await _taxService.GetProductPrice(product, (await _pricingService.GetUnitPrice(sci, product, false)).unitprice)).productprice; cartItemModel.UnitPriceWithoutDiscount = _priceFormatter.FormatPrice(cartItemModel.UnitPriceWithoutDiscountValue); cartItemModel.UnitPriceValue = productprices.productprice; cartItemModel.UnitPrice = _priceFormatter.FormatPrice(productprices.productprice); if (appliedDiscounts != null && appliedDiscounts.Any()) { var discount = await _discountService.GetDiscountById(appliedDiscounts.FirstOrDefault().DiscountId); if (discount != null && discount.MaximumDiscountedQuantity.HasValue) { cartItemModel.DiscountedQty = discount.MaximumDiscountedQuantity.Value; } foreach (var disc in appliedDiscounts) { cartItemModel.Discounts.Add(disc.DiscountId); } } //sub total var subtotal = await _pricingService.GetSubTotal(sci, product, true); decimal shoppingCartItemDiscountBase = subtotal.discountAmount; List <ApplyDiscount> scDiscounts = subtotal.appliedDiscounts; var shoppingCartItemSubTotalWithDiscount = (await _taxService.GetProductPrice(product, subtotal.subTotal)).productprice; cartItemModel.SubTotal = _priceFormatter.FormatPrice(shoppingCartItemSubTotalWithDiscount); cartItemModel.SubTotalValue = shoppingCartItemSubTotalWithDiscount; //display an applied discount amount if (shoppingCartItemDiscountBase > decimal.Zero) { shoppingCartItemDiscountBase = (await _taxService.GetProductPrice(product, shoppingCartItemDiscountBase)).productprice; if (shoppingCartItemDiscountBase > decimal.Zero) { cartItemModel.Discount = _priceFormatter.FormatPrice(shoppingCartItemDiscountBase); } } } //picture if (_shoppingCartSettings.ShowProductImagesOnShoppingCart) { cartItemModel.Picture = await PrepareCartItemPicture(product, sci.Attributes); } //item warnings var itemWarnings = await _shoppingCartValidator.GetShoppingCartItemWarnings(request.Customer, sci, product, new ShoppingCartValidatorOptions()); foreach (var warning in itemWarnings) { cartItemModel.Warnings.Add(warning); } model.Items.Add(cartItemModel); } #endregion }
public async Task <WishlistModel> Handle(GetWishlist request, CancellationToken cancellationToken) { var model = new WishlistModel { EmailWishlistEnabled = _shoppingCartSettings.EmailWishlistEnabled, IsEditable = request.IsEditable, DisplayAddToCart = await _permissionService.Authorize(StandardPermission.EnableShoppingCart), }; if (!request.Cart.Any()) { return(model); } #region Simple properties model.CustomerGuid = request.Customer.CustomerGuid; model.CustomerFullname = request.Customer.GetFullName(); model.ShowProductImages = _shoppingCartSettings.ShowProductImagesOnWishList; model.ShowSku = _catalogSettings.ShowSkuOnProductDetailsPage; //cart warnings var cartWarnings = await _shoppingCartValidator.GetShoppingCartWarnings(request.Cart, null, false); foreach (var warning in cartWarnings) { model.Warnings.Add(warning); } #endregion #region Cart items foreach (var sci in request.Cart) { var product = await _productService.GetProductById(sci.ProductId); if (!_aclService.Authorize(product, request.Customer)) { continue; } var sename = product.GetSeName(request.Language.Id); var cartItemModel = new WishlistModel.ShoppingCartItemModel { Id = sci.Id, Sku = product.FormatSku(sci.Attributes, _productAttributeParser), ProductId = product.Id, ProductName = product.GetTranslation(x => x.Name, request.Language.Id), ProductSeName = sename, ProductUrl = _linkGenerator.GetUriByRouteValues(_httpContextAccessor.HttpContext, "Product", new { SeName = sename }), Quantity = sci.Quantity, AttributeInfo = await _productAttributeFormatter.FormatAttributes(product, sci.Attributes), }; cartItemModel.AllowItemEditing = _shoppingCartSettings.AllowCartItemEditing && product.ProductTypeId == ProductType.SimpleProduct && (!String.IsNullOrEmpty(cartItemModel.AttributeInfo) || product.IsGiftVoucher) && product.VisibleIndividually; //allowed quantities var allowedQuantities = product.ParseAllowedQuantities(); foreach (var qty in allowedQuantities) { cartItemModel.AllowedQuantities.Add(new SelectListItem { Text = qty.ToString(), Value = qty.ToString(), Selected = sci.Quantity == qty }); } //recurring info if (product.IsRecurring) { cartItemModel.RecurringInfo = string.Format(_translationService.GetResource("ShoppingCart.RecurringPeriod"), product.RecurringCycleLength, product.RecurringCyclePeriodId.GetTranslationEnum(_translationService, request.Language.Id)); } //unit prices if (product.CallForPrice) { cartItemModel.UnitPrice = _translationService.GetResource("Products.CallForPrice"); } else { var productprice = await _taxService.GetProductPrice(product, (await _pricingService.GetUnitPrice(sci, product)).unitprice); double taxRate = productprice.taxRate; cartItemModel.UnitPrice = _priceFormatter.FormatPrice(productprice.productprice); } //subtotal, discount if (product.CallForPrice) { cartItemModel.SubTotal = _translationService.GetResource("Products.CallForPrice"); } else { //sub total var subtotal = await _pricingService.GetSubTotal(sci, product, true); double shoppingCartItemDiscountBase = subtotal.discountAmount; List <ApplyDiscount> scDiscounts = subtotal.appliedDiscounts; var productprices = await _taxService.GetProductPrice(product, subtotal.subTotal); double taxRate = productprices.taxRate; cartItemModel.SubTotal = _priceFormatter.FormatPrice(productprices.productprice); //display an applied discount amount if (shoppingCartItemDiscountBase > 0) { shoppingCartItemDiscountBase = (await _taxService.GetProductPrice(product, shoppingCartItemDiscountBase)).productprice; if (shoppingCartItemDiscountBase > 0) { cartItemModel.Discount = _priceFormatter.FormatPrice(shoppingCartItemDiscountBase); } } } //picture if (_shoppingCartSettings.ShowProductImagesOnWishList) { cartItemModel.Picture = await PrepareCartItemPicture(request, product, sci.Attributes); } //item warnings var itemWarnings = await _shoppingCartValidator.GetShoppingCartItemWarnings(request.Customer, sci, product, new ShoppingCartValidatorOptions()); foreach (var warning in itemWarnings) { cartItemModel.Warnings.Add(warning); } model.Items.Add(cartItemModel); } #endregion return(model); }
/// <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="attributes">Attributes</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 async Task <IList <string> > AddToCart(Customer customer, string productId, ShoppingCartType shoppingCartType, string storeId, string warehouseId = null, IList <CustomAttribute> attributes = null, decimal?customerEnteredPrice = null, DateTime?rentalStartDate = null, DateTime?rentalEndDate = null, int quantity = 1, bool automaticallyAddRequiredProductsIfEnabled = true, string reservationId = "", string parameter = "", string duration = "", bool getRequiredProductWarnings = true) { if (customer == null) { throw new ArgumentNullException(nameof(customer)); } var product = await _productService.GetProductById(productId); if (product == null) { throw new ArgumentNullException(nameof(product)); } var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartTypeId == shoppingCartType) .LimitPerStore(_shoppingCartSettings.SharedCartBetweenStores, storeId) .ToList(); var warnings = (await _shoppingCartValidator.CheckCommonWarnings(customer, cart, product, shoppingCartType, rentalStartDate, rentalEndDate, quantity, reservationId)).ToList(); if (warnings.Any()) { return(warnings); } var shoppingCartItem = await FindShoppingCartItem(cart, shoppingCartType, productId, warehouseId, attributes, customerEnteredPrice, rentalStartDate, rentalEndDate); var update = shoppingCartItem != null && product.ProductTypeId != ProductType.Reservation && String.IsNullOrEmpty(product.AllowedQuantities); if (update) { shoppingCartItem.Quantity += quantity; warnings.AddRange(await _shoppingCartValidator.GetShoppingCartItemWarnings(customer, shoppingCartItem, product, new ShoppingCartValidatorOptions() { GetRequiredProductWarnings = getRequiredProductWarnings })); } else { DateTime now = DateTime.UtcNow; shoppingCartItem = new ShoppingCartItem { ShoppingCartTypeId = shoppingCartType, StoreId = storeId, WarehouseId = warehouseId, ProductId = productId, Attributes = attributes, EnteredPrice = customerEnteredPrice, Quantity = quantity, RentalStartDateUtc = rentalStartDate, RentalEndDateUtc = rentalEndDate, AdditionalShippingChargeProduct = product.AdditionalShippingCharge, IsFreeShipping = product.IsFreeShipping, IsShipEnabled = product.IsShipEnabled, IsTaxExempt = product.IsTaxExempt, IsGiftVoucher = product.IsGiftVoucher, CreatedOnUtc = now, UpdatedOnUtc = now, ReservationId = reservationId, Parameter = parameter, Duration = duration }; warnings.AddRange(await _shoppingCartValidator.GetShoppingCartItemWarnings (customer, shoppingCartItem, product, new ShoppingCartValidatorOptions() { GetRequiredProductWarnings = getRequiredProductWarnings })); } if (!warnings.Any()) { if (update) { //update existing shopping cart item await UpdateExistingShoppingCartItem(shoppingCartItem, quantity, customer, product, attributes, getRequiredProductWarnings); } else { //insert new item shoppingCartItem = await InsertNewItem(customer, product, shoppingCartItem, automaticallyAddRequiredProductsIfEnabled); } await HandleCustomerReservation(customer, product, rentalStartDate, rentalEndDate, shoppingCartItem, reservationId); //reset checkout info await _customerService.ResetCheckoutData(customer, storeId); } return(warnings); }