public async Task <IActionResult> CheckProducts(string productids, string quantities) { var customer = await _workContext.GetCurrentCustomerAsync(); var carts = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, _storeContext.GetCurrentStore().Id); foreach (var item in carts) { await _shoppingCartService.DeleteShoppingCartItemAsync(item.Id); } var errorList = new List <CartErrorModel>(); int[] ids = null; if (!string.IsNullOrEmpty(productids)) { ids = Array.ConvertAll(productids.Split(","), s => int.Parse(s)); } int[] qtys = null; if (!string.IsNullOrEmpty(quantities)) { qtys = Array.ConvertAll(quantities.Split(","), s => int.Parse(s)); } var counter = 0; var products = await _productService.GetProductsByIdsAsync(ids); foreach (var product in products) { if (!product.Published || product.Deleted) { errorList.Add(new CartErrorModel { Success = false, Id = product.Id, Message = product.Name + " is not valid" }); } errorList.Add(await AddProductToCart(product.Id, qtys[counter])); counter++; } var cart = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, _storeContext.GetCurrentStore().Id); var cartTotal = await _orderTotalCalculationService.GetShoppingCartTotalAsync(cart, false); if (errorList.Any() && errorList.Where(x => !x.Success).Count() > 0) { return(Ok(new { success = false, errorList = errorList.Where(x => !x.Success), cartTotal = cartTotal.shoppingCartTotal })); } return(Ok(new { success = true, message = "All products are fine", cartTotal = cartTotal.shoppingCartTotal })); }
public async Task CanGetShoppingCartTotalWithoutShippingRequired() { await TearDown(); await SetUp(); //shipping is taxable, payment fee is taxable _taxSettings.ShippingIsTaxable = true; _taxSettings.PaymentMethodAdditionalFeeIsTaxable = true; await _settingService.SaveSettingAsync(_taxSettings); TestPaymentMethod.AdditionalHandlingFee = 20M; //207 - items, 20 - payment fee, 22.7 - tax var(cartTotal, _, _, _, _, _) = await _orderTotalCalcService.GetShoppingCartTotalAsync(await GetShoppingCartAsync()); cartTotal.Should().Be(249.7M); TestPaymentMethod.AdditionalHandlingFee = 0M; }
/// <summary> /// Returns the value indicating whether to payment method can be displayed in checkout /// </summary> /// <param name="cart">The shopping cart</param> /// <returns>The <see cref="Task"/> containing the value indicating whether to payment method can be displayed in checkout</returns> public virtual async Task <bool> CanDisplayPaymentMethodAsync(IList <ShoppingCartItem> cart) { if (cart is null) { throw new ArgumentNullException(nameof(cart)); } if (!(await ValidateAsync()).IsValid) { return(false); } if (_openPayPaymentSettings.MinOrderTotal == 0 || _openPayPaymentSettings.MaxOrderTotal == 0) { return(false); } var cartTotal = await _orderTotalCalculationService.GetShoppingCartTotalAsync(cart); decimal shoppingCartTotal; if (cartTotal.shoppingCartTotal.HasValue) { shoppingCartTotal = cartTotal.shoppingCartTotal.Value; } else { var cartSubTotal = await _orderTotalCalculationService.GetShoppingCartSubTotalAsync(cart, true); shoppingCartTotal = cartSubTotal.subTotalWithDiscount; } if (shoppingCartTotal < _openPayPaymentSettings.MinOrderTotal || shoppingCartTotal > _openPayPaymentSettings.MaxOrderTotal) { return(false); } if (!await _shoppingCartService.ShoppingCartRequiresShippingAsync(cart)) { return(false); } return(true); }
/// <summary> /// Handle shopping cart changed event /// </summary> /// <param name="cartItem">Shopping cart item</param> /// <returns>A task that represents the asynchronous operation</returns> public async Task HandleShoppingCartChangedEventAsync(ShoppingCartItem cartItem) { //whether marketing automation is enabled if (!_sendinblueSettings.UseMarketingAutomation) { return; } var customer = await _customerService.GetCustomerByIdAsync(cartItem.CustomerId); try { //create API client var client = CreateMarketingAutomationClient(); //first, try to identify current customer await client.IdentifyAsync(new Identify(customer.Email)); //get shopping cart GUID var shoppingCartGuid = await _genericAttributeService .GetAttributeAsync <Guid?>(customer, SendinblueDefaults.ShoppingCartGuidAttribute); //create track event object var trackEvent = new TrackEvent(customer.Email, string.Empty); //get current customer's shopping cart var store = await _storeContext.GetCurrentStoreAsync(); var cart = await _shoppingCartService .GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, store.Id); if (cart.Any()) { //get URL helper var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext); //get shopping cart amounts var(_, cartDiscount, _, cartSubtotal, _) = await _orderTotalCalculationService.GetShoppingCartSubTotalAsync(cart, await _workContext.GetTaxDisplayTypeAsync() == TaxDisplayType.IncludingTax); var cartTax = await _orderTotalCalculationService.GetTaxTotalAsync(cart, false); var cartShipping = await _orderTotalCalculationService.GetShoppingCartShippingTotalAsync(cart); var(cartTotal, _, _, _, _, _) = await _orderTotalCalculationService.GetShoppingCartTotalAsync(cart, false, false); //get products data by shopping cart items var itemsData = await cart.Where(item => item.ProductId != 0).SelectAwait(async item => { var product = await _productService.GetProductByIdAsync(item.ProductId); //try to get product attribute combination var combination = await _productAttributeParser.FindProductAttributeCombinationAsync(product, item.AttributesXml); //get default product picture var picture = await _pictureService.GetProductPictureAsync(product, item.AttributesXml); //get product SEO slug name var seName = await _urlRecordService.GetSeNameAsync(product); //create product data return(new { id = product.Id, name = product.Name, variant_id = combination?.Id ?? product.Id, variant_name = combination?.Sku ?? product.Name, sku = combination?.Sku ?? product.Sku, category = await(await _categoryService.GetProductCategoriesByProductIdAsync(item.ProductId)).AggregateAwaitAsync(",", async(all, pc) => { var res = (await _categoryService.GetCategoryByIdAsync(pc.CategoryId)).Name; res = all == "," ? res : all + ", " + res; return res; }), url = urlHelper.RouteUrl("Product", new { SeName = seName }, _webHelper.GetCurrentRequestProtocol()), image = (await _pictureService.GetPictureUrlAsync(picture)).Url, quantity = item.Quantity, price = (await _shoppingCartService.GetSubTotalAsync(item, true)).subTotal }); }).ToArrayAsync(); //prepare cart data var cartData = new { affiliation = store.Name, subtotal = cartSubtotal, shipping = cartShipping ?? decimal.Zero, total_before_tax = cartSubtotal + cartShipping ?? decimal.Zero, tax = cartTax, discount = cartDiscount, revenue = cartTotal ?? decimal.Zero, url = urlHelper.RouteUrl("ShoppingCart", null, _webHelper.GetCurrentRequestProtocol()), currency = (await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId))?.CurrencyCode, //gift_wrapping = string.Empty, //currently we can't get this value items = itemsData }; //if there is a single item in the cart, so the cart is just created if (cart.Count == 1) { shoppingCartGuid = Guid.NewGuid(); } else { //otherwise cart is updated shoppingCartGuid ??= Guid.NewGuid(); } trackEvent.EventName = SendinblueDefaults.CartUpdatedEventName; trackEvent.EventData = new { id = $"cart:{shoppingCartGuid}", data = cartData }; } else { //there are no items in the cart, so the cart is deleted shoppingCartGuid ??= Guid.NewGuid(); trackEvent.EventName = SendinblueDefaults.CartDeletedEventName; trackEvent.EventData = new { id = $"cart:{shoppingCartGuid}" }; } //track event await client.TrackEventAsync(trackEvent); //update GUID for the current customer's shopping cart await _genericAttributeService.SaveAttributeAsync(customer, SendinblueDefaults.ShoppingCartGuidAttribute, shoppingCartGuid); } catch (Exception exception) { //log full error await _logger.ErrorAsync($"Sendinblue Marketing Automation error: {exception.Message}.", exception, customer); } }
/// <summary> /// Invokes the view component /// </summary> /// <param name="widgetZone">Widget zone name</param> /// <param name="additionalData">Additional data</param> /// <returns>The <see cref="Task"/> containing the <see cref="IViewComponentResult"/></returns> public async Task <IViewComponentResult> InvokeAsync(string widgetZone, object additionalData) { if (!await _openPayService.CanDisplayWidgetAsync()) { return(Content(string.Empty)); } if (widgetZone == PublicWidgetZones.BodyEndHtmlTagBefore) { if (!_openPayPaymentSettings.DisplayLandingPageWidget) { return(Content(string.Empty)); } return(View("~/Plugins/Payments.OpenPay/Views/Widget/LandingPageLink.cshtml")); } var region = Defaults.OpenPay.AvailableRegions.FirstOrDefault( region => region.IsSandbox == _openPayPaymentSettings.UseSandbox && region.TwoLetterIsoCode == _openPayPaymentSettings.RegionTwoLetterIsoCode); var workingCurrency = await _workContext.GetWorkingCurrencyAsync(); Task <decimal> toWorkingCurrencyAsync(decimal price) => _currencyService.ConvertFromPrimaryStoreCurrencyAsync(price, workingCurrency); var model = new WidgetModel { WidgetCode = region.WidgetCode, RegionCode = region.TwoLetterIsoCode, CurrencyCode = workingCurrency.CurrencyCode, CurrencyFormatting = workingCurrency.CustomFormatting, PlanTiers = _openPayPaymentSettings.PlanTiers.Split(',').Select(x => int.Parse(x)).ToArray(), MinEligibleAmount = await toWorkingCurrencyAsync(_openPayPaymentSettings.MinOrderTotal), MaxEligibleAmount = await toWorkingCurrencyAsync(_openPayPaymentSettings.MaxOrderTotal), Type = "Online" }; if (widgetZone == PublicWidgetZones.ProductDetailsBottom && additionalData is ProductDetailsModel productDetailsModel) { if (!_openPayPaymentSettings.DisplayProductPageWidget) { return(Content(string.Empty)); } var product = await _productService.GetProductByIdAsync(productDetailsModel.Id); if (product == null || product.Deleted || product.IsDownload || !product.IsShipEnabled) { return(Content(string.Empty)); } model.Logo = _openPayPaymentSettings.ProductPageWidgetLogo; model.LogoPosition = _openPayPaymentSettings.ProductPageWidgetLogoPosition; model.Amount = productDetailsModel.ProductPrice.PriceValue; return(View("~/Plugins/Payments.OpenPay/Views/Widget/ProductPage.cshtml", model)); } if (widgetZone == PublicWidgetZones.ProductBoxAddinfoMiddle && additionalData is ProductOverviewModel productOverviewModel) { if (!_openPayPaymentSettings.DisplayProductListingWidget) { return(Content(string.Empty)); } var product = await _productService.GetProductByIdAsync(productOverviewModel.Id); if (product == null || product.Deleted || product.IsDownload || !product.IsShipEnabled) { return(Content(string.Empty)); } model.Logo = _openPayPaymentSettings.ProductListingWidgetLogo; model.HideLogo = _openPayPaymentSettings.ProductListingHideLogo; model.Amount = productOverviewModel.ProductPrice.PriceValue ?? decimal.Zero; return(View("~/Plugins/Payments.OpenPay/Views/Widget/ProductListing.cshtml", model)); } if (widgetZone == PublicWidgetZones.OrderSummaryContentAfter) { if (!_openPayPaymentSettings.DisplayCartWidget) { return(Content(string.Empty)); } var routeName = HttpContext.GetEndpoint()?.Metadata.GetMetadata <RouteNameMetadata>()?.RouteName; if (routeName != Defaults.ShoppingCartRouteName) { return(Content(string.Empty)); } var customer = await _workContext.GetCurrentCustomerAsync(); var store = await _storeContext.GetCurrentStoreAsync(); var cart = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, store.Id); if (cart == null || !cart.Any()) { return(Content(string.Empty)); } if (!await _shoppingCartService.ShoppingCartRequiresShippingAsync(cart)) { return(Content(string.Empty)); } var shoppingCartTotal = decimal.Zero; var cartTotal = await _orderTotalCalculationService.GetShoppingCartTotalAsync(cart); if (cartTotal.shoppingCartTotal.HasValue) { shoppingCartTotal = cartTotal.shoppingCartTotal.Value; } else { var cartSubTotal = await _orderTotalCalculationService.GetShoppingCartSubTotalAsync(cart, true); shoppingCartTotal = cartSubTotal.subTotalWithDiscount; } model.Logo = _openPayPaymentSettings.CartWidgetLogo; model.Amount = await toWorkingCurrencyAsync(shoppingCartTotal); return(View("~/Plugins/Payments.OpenPay/Views/Widget/Cart.cshtml", model)); } if (widgetZone == PublicWidgetZones.BodyStartHtmlTagAfter) { if (!_openPayPaymentSettings.DisplayInfoBeltWidget) { return(Content(string.Empty)); } model.Color = _openPayPaymentSettings.InfoBeltWidgetColor; return(View("~/Plugins/Payments.OpenPay/Views/Widget/InfoBelt.cshtml", model)); } if (widgetZone == "OpenPayLandingPage") { if (!_openPayPaymentSettings.DisplayLandingPageWidget) { return(Content(string.Empty)); } return(View("~/Plugins/Payments.OpenPay/Views/Widget/LandingPage.cshtml", model)); } return(Content(string.Empty)); }