public override decimal? GetShoppingCartTotal(IList<global::Nop.Core.Domain.Orders.ShoppingCartItem> cart, out decimal discountAmount, out global::Nop.Core.Domain.Discounts.Discount appliedDiscount, out List<AppliedGiftCard> appliedGiftCards, out int redeemedRewardPoints, out decimal redeemedRewardPointsAmount, bool ignoreRewardPonts = false, bool usePaymentMethodAdditionalFee = true)
        {
            if (!_promoSettings.Enabled)
                return base.GetShoppingCartTotal(cart, out discountAmount, out appliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount, ignoreRewardPonts, usePaymentMethodAdditionalFee);

            BasketResponse basketResponse = _promoUtilities.GetBasketResponse();

            if (basketResponse == null || basketResponse.Items == null || basketResponse.Summary == null)
            {
                return base.GetShoppingCartTotal(cart, out discountAmount, out appliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount, ignoreRewardPonts, usePaymentMethodAdditionalFee);
            }

            if (!basketResponse.Summary.ProcessingResult)
            {
                return base.GetShoppingCartTotal(cart, out discountAmount, out appliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount, ignoreRewardPonts, usePaymentMethodAdditionalFee);
            }

            Customer customer = cart.GetCustomer();

            discountAmount = decimal.Zero;
            appliedDiscount = null;
            decimal resultTemp = basketResponse.BasketTotal;

            #region Applied gift cards

            appliedGiftCards = new List<AppliedGiftCard>();
            if (!cart.IsRecurring())
            {
                //we don't apply gift cards for recurring products
                var giftCards = _giftCardService.GetActiveGiftCardsAppliedByCustomer(customer);
                if (giftCards != null)
                    foreach (var gc in giftCards)
                        if (resultTemp > decimal.Zero)
                        {
                            decimal remainingAmount = gc.GetGiftCardRemainingAmount();
                            decimal amountCanBeUsed = decimal.Zero;
                            if (resultTemp > remainingAmount)
                                amountCanBeUsed = remainingAmount;
                            else
                                amountCanBeUsed = resultTemp;

                            //reduce subtotal
                            resultTemp -= amountCanBeUsed;

                            var appliedGiftCard = new AppliedGiftCard();
                            appliedGiftCard.GiftCard = gc;
                            appliedGiftCard.AmountCanBeUsed = amountCanBeUsed;
                            appliedGiftCards.Add(appliedGiftCard);
                        }
            }

            if (resultTemp < decimal.Zero)
                resultTemp = decimal.Zero;
            if (_shoppingCartSettings.RoundPricesDuringCalculation)
                resultTemp = RoundingHelper.RoundPrice(resultTemp);

            #endregion

            redeemedRewardPoints = 0;
            redeemedRewardPointsAmount = Decimal.Zero;

            decimal orderTotal = basketResponse.BasketTotal - appliedGiftCards.Sum(agc => agc.AmountCanBeUsed);

            #region Reward points

            if (_rewardPointsSettings.Enabled &&
                !ignoreRewardPonts &&
                customer.GetAttribute<bool>(SystemCustomerAttributeNames.UseRewardPointsDuringCheckout,
                    _genericAttributeService, _storeContext.CurrentStore.Id))
            {
                int rewardPointsBalance = customer.GetRewardPointsBalance();
                if (CheckMinimumRewardPointsToUseRequirement(rewardPointsBalance))
                {
                    decimal rewardPointsBalanceAmount = ConvertRewardPointsToAmount(rewardPointsBalance);
                    if (orderTotal > decimal.Zero)
                    {
                        if (orderTotal > rewardPointsBalanceAmount)
                        {
                            redeemedRewardPoints = rewardPointsBalance;
                            redeemedRewardPointsAmount = rewardPointsBalanceAmount;
                        }
                        else
                        {
                            redeemedRewardPointsAmount = orderTotal;
                            redeemedRewardPoints = ConvertAmountToRewardPoints(redeemedRewardPointsAmount);
                        }
                    }
                }
            }

            #endregion

            var shippingOption = _workContext.CurrentCustomer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id);
            if (shippingOption == null)
            {
                // Where there are items in the basket that are not for shipping, ensure we carry on, otherwise placing orders gets stuck.
                if(cart.Any(sci => sci.IsShipEnabled))
                    return null;                
            }

            discountAmount = basketResponse.OrderDiscountTotal();
            if (discountAmount > 0)
            {
                appliedDiscount = new Discount()
                {
                    Name = basketResponse.BasketLevelPromotion().PromotionName,
                    DiscountAmount = discountAmount
                };
            }

            decimal tax = GetTaxTotal(cart);

            return basketResponse.BasketTotal + tax - appliedGiftCards.Sum(agc => agc.AmountCanBeUsed) - redeemedRewardPointsAmount;
        }