Example #1
0
        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);
            }
        }
Example #5
0
        /// <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));
        }