Пример #1
0
        public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            try
            {
                var options     = IyzicoHelper.GetIyzicoOptions(_iyzicoPaymentSettings);
                var paymentCard = new PaymentCard()
                {
                    CardHolderName = processPaymentRequest.CreditCardName,
                    CardNumber     = processPaymentRequest.CreditCardNumber,
                    ExpireMonth    = processPaymentRequest.CreditCardExpireMonth.ToString(),
                    ExpireYear     = processPaymentRequest.CreditCardExpireYear.ToString(),
                    Cvc            = processPaymentRequest.CreditCardCvv2
                };

                var customer        = _customerService.GetCustomerById(processPaymentRequest.CustomerId);
                var billingAddress  = _iyzicoService.PrepareAddress(_customerService.GetCustomerBillingAddress(customer));
                var shippingAddress = _customerService.GetCustomerShippingAddress(customer) != null?_iyzicoService.PrepareAddress(_customerService.GetCustomerShippingAddress(customer)) : billingAddress;

                var installment = GetInstallment(processPaymentRequest, paymentCard, options);

                var shoppingCart      = _shoppingCartService.GetShoppingCart(customer, ShoppingCartType.ShoppingCart);
                var shoppingCartTotal = _orderTotalCalculationService.GetShoppingCartTotal(shoppingCart, out var orderDiscountAmount, out var orderAppliedDiscounts, out var appliedGiftCards, out var redeemedRewardPoints, out var redeemedRewardPointsAmount, usePaymentMethodAdditionalFee: false);

                var paymentRequest = new CreatePaymentRequest
                {
                    Price           = _priceCalculationService.RoundPrice(shoppingCartTotal ?? 0).ToString("f8", CultureInfo.InvariantCulture),
                    PaidPrice       = installment.TotalPrice,
                    Currency        = Currency.TRY.ToString(),
                    Installment     = installment.InstallmentNumber,
                    BasketId        = processPaymentRequest.OrderGuid.ToString(),
                    PaymentCard     = paymentCard,
                    Buyer           = _iyzicoService.PrepareBuyer(processPaymentRequest.CustomerId),
                    ShippingAddress = shippingAddress,
                    BillingAddress  = billingAddress,
                    BasketItems     = GetItems(customer, processPaymentRequest.StoreId)
                };
                paymentRequest.PaymentGroup = PaymentGroup.LISTING.ToString();

                var payment = Payment.Create(paymentRequest, options);
                if (payment.Status != "success")
                {
                    string errorMessage = _localizationService.GetResource(String.Format("Plugins.Payments.Iyzico.ErrorMessage.{0}", payment.ErrorCode)) ?? payment.ErrorMessage;
                    result.AddError(errorMessage);
                    return(result);
                }

                result.NewPaymentStatus = PaymentStatus.Pending;

                return(result);
            }
            catch (Exception ex)
            {
                result.AddError(ex.Message);
                return(result);
            }
        }
Пример #2
0
        public virtual IActionResult GetInstallment(string binNumber)
        {
            if (String.IsNullOrEmpty(binNumber))
            {
                return(Json(String.Empty));
            }

            var customer          = _customerService.GetCustomerById(_workContext.CurrentCustomer.Id);
            var shoppingCart      = _shoppingCartService.GetShoppingCart(customer, ShoppingCartType.ShoppingCart);
            var shoppingCartTotal = _orderTotalCalculationService.GetShoppingCartTotal(shoppingCart, out var orderDiscountAmount, out var orderAppliedDiscounts, out var appliedGiftCards, out var redeemedRewardPoints, out var redeemedRewardPointsAmount);

            var options = IyzicoHelper.GetIyzicoOptions(_iyzicoPaymentSettings);
            var retrieveInstallmentInfoRequest = new RetrieveInstallmentInfoRequest()
            {
                BinNumber      = binNumber.ToString(),
                Locale         = Locale.TR.ToString(),
                Price          = _priceCalculationService.RoundPrice(shoppingCartTotal.Value).ToString("f8", CultureInfo.InvariantCulture),
                ConversationId = string.Empty
            };
            var installmentInfo = InstallmentInfo.Retrieve(retrieveInstallmentInfoRequest, options);

            var subTotalIncludingTax = _workContext.TaxDisplayType == TaxDisplayType.IncludingTax && !_taxSettings.ForceTaxExclusionFromOrderSubtotal;
            var subtotal             = decimal.Zero;
            var list = new List <Installment>();

            if (installmentInfo.Status == "success" && installmentInfo.InstallmentDetails.Count > 0)
            {
                foreach (var installmentDetail in installmentInfo.InstallmentDetails.FirstOrDefault().InstallmentPrices)
                {
                    var installment = new Installment();

                    installment.DisplayName       = _localizationService.GetResource("Plugins.Payments.Iyzico.Installment" + installmentDetail.InstallmentNumber);
                    installment.InstallmentNumber = installmentDetail.InstallmentNumber ?? 0;
                    decimal.TryParse(installmentDetail.Price.Replace(".", ","), out decimal price);
                    installment.Price = _priceFormatter.FormatPrice(price, true, _workContext.WorkingCurrency, _workContext.WorkingLanguage.Id, subTotalIncludingTax);
                    decimal.TryParse(installmentDetail.TotalPrice.Replace(".", ","), out decimal totalPrice);
                    installment.TotalPrice = _priceFormatter.FormatPrice(totalPrice, true, _workContext.WorkingCurrency, _workContext.WorkingLanguage.Id, subTotalIncludingTax);

                    list.Add(installment);
                }
            }
            else
            {
                subtotal = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartTotal ?? 0, _workContext.WorkingCurrency);

                list.Add(new Installment()
                {
                    DisplayName       = _localizationService.GetResource("Plugins.Payments.Iyzico.Installment1"),
                    InstallmentNumber = 1,
                    Price             = _priceFormatter.FormatPrice(subtotal, true, _workContext.WorkingCurrency, _workContext.WorkingLanguage.Id, subTotalIncludingTax),
                    TotalPrice        = _priceFormatter.FormatPrice(subtotal, true, _workContext.WorkingCurrency, _workContext.WorkingLanguage.Id, subTotalIncludingTax)
                });
            }

            return(Json(list));
        }
Пример #3
0
        /// <summary>
        /// Generate a feed
        /// </summary>
        /// <param name="stream">Stream</param>
        /// <param name="store">Store</param>
        /// <returns>Generated feed</returns>
        public void GenerateFeed(Stream stream, Store store)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (store == null)
            {
                throw new ArgumentNullException(nameof(store));
            }

            const string googleBaseNamespace = "http://base.google.com/ns/1.0";

            var settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8
            };

            var googleShoppingSettings = _settingService.LoadSetting <GoogleShoppingSettings>(store.Id);

            //language
            var languageId = 0;
            var languages  = _languageService.GetAllLanguages(storeId: store.Id);

            //if we have only one language, let's use it
            if (languages.Count == 1)
            {
                //let's use the first one
                var language = languages.FirstOrDefault();
                languageId = language != null ? language.Id : 0;
            }
            //otherwise, use the current one
            if (languageId == 0)
            {
                languageId = _workContext.WorkingLanguage.Id;
            }

            //we load all Google products here using one SQL request (performance optimization)
            var allGoogleProducts = _googleService.GetAll();

            using (var writer = XmlWriter.Create(stream, settings))
            {
                //Generate feed according to the following specs: http://www.google.com/support/merchants/bin/answer.py?answer=188494&expand=GB
                writer.WriteStartDocument();
                writer.WriteStartElement("rss");
                writer.WriteAttributeString("version", "2.0");
                writer.WriteAttributeString("xmlns", "g", null, googleBaseNamespace);
                writer.WriteStartElement("channel");
                writer.WriteElementString("title", "Google Base feed");
                writer.WriteElementString("link", "http://base.google.com/base/");
                writer.WriteElementString("description", "Information about products");

                var products1 = _productService.SearchProducts(storeId: store.Id, visibleIndividuallyOnly: true);
                foreach (var product1 in products1)
                {
                    var productsToProcess = new List <Product>();
                    switch (product1.ProductType)
                    {
                    case ProductType.SimpleProduct:
                    {
                        //simple product doesn't have child products
                        productsToProcess.Add(product1);
                    }
                    break;

                    case ProductType.GroupedProduct:
                    {
                        //grouped products could have several child products
                        var associatedProducts = _productService.GetAssociatedProducts(product1.Id, store.Id);
                        productsToProcess.AddRange(associatedProducts);
                    }
                    break;

                    default:
                        continue;
                    }
                    foreach (var product in productsToProcess)
                    {
                        writer.WriteStartElement("item");

                        #region Basic Product Information

                        //id [id]- An identifier of the item
                        writer.WriteElementString("g", "id", googleBaseNamespace, product.Id.ToString());

                        //title [title] - Title of the item
                        writer.WriteStartElement("title");
                        var title = _localizationService.GetLocalized(product, x => x.Name, languageId);
                        //title should be not longer than 70 characters
                        if (title.Length > 70)
                        {
                            title = title.Substring(0, 70);
                        }
                        writer.WriteCData(title);
                        writer.WriteEndElement(); // title

                        //description [description] - Description of the item
                        writer.WriteStartElement("description");
                        var description = _localizationService.GetLocalized(product, x => x.FullDescription, languageId);
                        if (string.IsNullOrEmpty(description))
                        {
                            description = _localizationService.GetLocalized(product, x => x.ShortDescription, languageId);
                        }
                        if (string.IsNullOrEmpty(description))
                        {
                            description = _localizationService.GetLocalized(product, x => x.Name, languageId); //description is required
                        }
                        //resolving character encoding issues in your data feed
                        description = StripInvalidChars(description, true);
                        writer.WriteCData(description);
                        writer.WriteEndElement(); // description

                        //google product category [google_product_category] - Google's category of the item
                        //the category of the product according to Google’s product taxonomy. http://www.google.com/support/merchants/bin/answer.py?answer=160081
                        var googleProductCategory = "";
                        //var googleProduct = _googleService.GetByProductId(product.Id);
                        var googleProduct = allGoogleProducts.FirstOrDefault(x => x.ProductId == product.Id);
                        if (googleProduct != null)
                        {
                            googleProductCategory = googleProduct.Taxonomy;
                        }
                        if (string.IsNullOrEmpty(googleProductCategory))
                        {
                            googleProductCategory = googleShoppingSettings.DefaultGoogleCategory;
                        }
                        if (string.IsNullOrEmpty(googleProductCategory))
                        {
                            throw new NopException("Default Google category is not set");
                        }
                        writer.WriteStartElement("g", "google_product_category", googleBaseNamespace);
                        writer.WriteCData(googleProductCategory);
                        writer.WriteFullEndElement(); // g:google_product_category

                        //product type [product_type] - Your category of the item
                        var defaultProductCategory = _categoryService
                                                     .GetProductCategoriesByProductId(product.Id, store.Id)
                                                     .FirstOrDefault();
                        if (defaultProductCategory != null)
                        {
                            //TODO localize categories
                            var category = _categoryService.GetFormattedBreadCrumb(defaultProductCategory.Category, separator: ">", languageId: languageId);
                            if (!string.IsNullOrEmpty(category))
                            {
                                writer.WriteStartElement("g", "product_type", googleBaseNamespace);
                                writer.WriteCData(category);
                                writer.WriteFullEndElement(); // g:product_type
                            }
                        }

                        //link [link] - URL directly linking to your item's page on your website
                        var productUrl = GetUrlHelper().RouteUrl("Product", new { SeName = _urlRecordService.GetSeName(product) }, GetHttpProtocol());
                        writer.WriteElementString("link", productUrl);

                        //image link [image_link] - URL of an image of the item
                        //additional images [additional_image_link]
                        //up to 10 pictures
                        const int maximumPictures = 10;
                        var       storeLocation   = _webHelper.GetStoreLocation(_securitySettings.ForceSslForAllPages);
                        var       pictures        = _pictureService.GetPicturesByProductId(product.Id, maximumPictures);
                        for (var i = 0; i < pictures.Count; i++)
                        {
                            var picture  = pictures[i];
                            var imageUrl = _pictureService.GetPictureUrl(picture,
                                                                         googleShoppingSettings.ProductPictureSize,
                                                                         storeLocation: storeLocation);

                            if (i == 0)
                            {
                                //default image
                                writer.WriteElementString("g", "image_link", googleBaseNamespace, imageUrl);
                            }
                            else
                            {
                                //additional image
                                writer.WriteElementString("g", "additional_image_link", googleBaseNamespace, imageUrl);
                            }
                        }
                        if (!pictures.Any())
                        {
                            //no picture? submit a default one
                            var imageUrl = _pictureService.GetDefaultPictureUrl(googleShoppingSettings.ProductPictureSize, storeLocation: storeLocation);
                            writer.WriteElementString("g", "image_link", googleBaseNamespace, imageUrl);
                        }

                        //condition [condition] - Condition or state of the item
                        writer.WriteElementString("g", "condition", googleBaseNamespace, "new");

                        writer.WriteElementString("g", "expiration_date", googleBaseNamespace, DateTime.Now.AddDays(googleShoppingSettings.ExpirationNumberOfDays).ToString("yyyy-MM-dd"));

                        #endregion

                        #region Availability & Price

                        //availability [availability] - Availability status of the item
                        var availability = "in stock"; //in stock by default
                        if (product.ManageInventoryMethod == ManageInventoryMethod.ManageStock &&
                            product.BackorderMode == BackorderMode.NoBackorders &&
                            _productService.GetTotalStockQuantity(product) <= 0)
                        {
                            availability = "out of stock";
                        }
                        //uncomment th code below in order to support "preorder" value for "availability"
                        //if (product.AvailableForPreOrder &&
                        //    (!product.PreOrderAvailabilityStartDateTimeUtc.HasValue ||
                        //    product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow))
                        //{
                        //    availability = "preorder";
                        //}
                        writer.WriteElementString("g", "availability", googleBaseNamespace, availability);

                        //price [price] - Price of the item
                        var     currency = GetUsedCurrency();
                        decimal finalPriceBase;
                        if (googleShoppingSettings.PricesConsiderPromotions)
                        {
                            var minPossiblePrice = _priceCalculationService.GetFinalPrice(product, _workContext.CurrentCustomer);

                            if (product.HasTierPrices)
                            {
                                //calculate price for the maximum quantity if we have tier prices, and choose minimal
                                minPossiblePrice = Math.Min(minPossiblePrice,
                                                            _priceCalculationService.GetFinalPrice(product, _workContext.CurrentCustomer, quantity: int.MaxValue));
                            }

                            finalPriceBase = _taxService.GetProductPrice(product, minPossiblePrice, out var _);
                        }
                        else
                        {
                            finalPriceBase = product.Price;
                        }
                        var price = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, currency);
                        //round price now so it matches the product details page
                        price = _priceCalculationService.RoundPrice(price);

                        writer.WriteElementString("g", "price", googleBaseNamespace,
                                                  price.ToString(new CultureInfo("en-US", false).NumberFormat) + " " +
                                                  currency.CurrencyCode);

                        #endregion

                        #region Unique Product Identifiers

                        /* Unique product identifiers such as UPC, EAN, JAN or ISBN allow us to show your listing on the appropriate product page. If you don't provide the required unique product identifiers, your store may not appear on product pages, and all your items may be removed from Product Search.
                         * We require unique product identifiers for all products - except for custom made goods. For apparel, you must submit the 'brand' attribute. For media (such as books, movies, music and video games), you must submit the 'gtin' attribute. In all cases, we recommend you submit all three attributes.
                         * You need to submit at least two attributes of 'brand', 'gtin' and 'mpn', but we recommend that you submit all three if available. For media (such as books, movies, music and video games), you must submit the 'gtin' attribute, but we recommend that you include 'brand' and 'mpn' if available.
                         */

                        //GTIN [gtin] - GTIN
                        var gtin = product.Gtin;
                        if (!string.IsNullOrEmpty(gtin))
                        {
                            writer.WriteStartElement("g", "gtin", googleBaseNamespace);
                            writer.WriteCData(gtin);
                            writer.WriteFullEndElement(); // g:gtin
                        }

                        //brand [brand] - Brand of the item
                        var defaultManufacturer = _manufacturerService.GetProductManufacturersByProductId(product.Id).FirstOrDefault();
                        if (defaultManufacturer != null)
                        {
                            writer.WriteStartElement("g", "brand", googleBaseNamespace);
                            writer.WriteCData(defaultManufacturer.Manufacturer.Name);
                            writer.WriteFullEndElement(); // g:brand
                        }

                        //mpn [mpn] - Manufacturer Part Number (MPN) of the item
                        var mpn = product.ManufacturerPartNumber;
                        if (!string.IsNullOrEmpty(mpn))
                        {
                            writer.WriteStartElement("g", "mpn", googleBaseNamespace);
                            writer.WriteCData(mpn);
                            writer.WriteFullEndElement(); // g:mpn
                        }

                        //identifier exists [identifier_exists] - Submit custom goods
                        if (googleProduct != null && googleProduct.CustomGoods)
                        {
                            writer.WriteElementString("g", "identifier_exists", googleBaseNamespace, "FALSE");
                        }

                        #endregion

                        #region Apparel Products

                        /* Apparel includes all products that fall under 'Apparel & Accessories' (including all sub-categories)
                         * in Google’s product taxonomy.
                         */

                        //gender [gender] - Gender of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.Gender))
                        {
                            writer.WriteStartElement("g", "gender", googleBaseNamespace);
                            writer.WriteCData(googleProduct.Gender);
                            writer.WriteFullEndElement(); // g:gender
                        }

                        //age group [age_group] - Target age group of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.AgeGroup))
                        {
                            writer.WriteStartElement("g", "age_group", googleBaseNamespace);
                            writer.WriteCData(googleProduct.AgeGroup);
                            writer.WriteFullEndElement(); // g:age_group
                        }

                        //color [color] - Color of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.Color))
                        {
                            writer.WriteStartElement("g", "color", googleBaseNamespace);
                            writer.WriteCData(googleProduct.Color);
                            writer.WriteFullEndElement(); // g:color
                        }

                        //size [size] - Size of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.Size))
                        {
                            writer.WriteStartElement("g", "size", googleBaseNamespace);
                            writer.WriteCData(googleProduct.Size);
                            writer.WriteFullEndElement(); // g:size
                        }

                        #endregion

                        #region Tax & Shipping

                        //tax [tax]
                        //The tax attribute is an item-level override for merchant-level tax settings as defined in your Google Merchant Center account. This attribute is only accepted in the US, if your feed targets a country outside of the US, please do not use this attribute.
                        //IMPORTANT NOTE: Set tax in your Google Merchant Center account settings

                        //IMPORTANT NOTE: Set shipping in your Google Merchant Center account settings

                        //shipping weight [shipping_weight] - Weight of the item for shipping
                        //We accept only the following units of weight: lb, oz, g, kg.
                        if (googleShoppingSettings.PassShippingInfoWeight)
                        {
                            string weightName;
                            var    shippingWeight   = product.Weight;
                            var    weightSystemName = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).SystemKeyword;
                            switch (weightSystemName)
                            {
                            case "ounce":
                                weightName = "oz";
                                break;

                            case "lb":
                                weightName = "lb";
                                break;

                            case "grams":
                                weightName = "g";
                                break;

                            case "kg":
                                weightName = "kg";
                                break;

                            default:
                                //unknown weight
                                throw new Exception("Not supported weight. Google accepts the following units: lb, oz, g, kg.");
                            }
                            writer.WriteElementString("g", "shipping_weight", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", shippingWeight.ToString(new CultureInfo("en-US", false).NumberFormat), weightName));
                        }

                        //shipping length [shipping_length] - Length of the item for shipping
                        //shipping width [shipping_width] - Width of the item for shipping
                        //shipping height [shipping_height] - Height of the item for shipping
                        //We accept only the following units of length: in, cm
                        if (googleShoppingSettings.PassShippingInfoDimensions)
                        {
                            string dimensionName;
                            var    length = product.Length;
                            var    width  = product.Width;
                            var    height = product.Height;
                            var    dimensionSystemName = _measureService.GetMeasureDimensionById(_measureSettings.BaseDimensionId).SystemKeyword;
                            switch (dimensionSystemName)
                            {
                            case "inches":
                                dimensionName = "in";
                                break;

                            //TODO support other dimensions (convert to cm)
                            default:
                                //unknown dimension
                                throw new Exception("Not supported dimension. Google accepts the following units: in, cm.");
                            }
                            writer.WriteElementString("g", "shipping_length", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", length.ToString(new CultureInfo("en-US", false).NumberFormat), dimensionName));
                            writer.WriteElementString("g", "shipping_width", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", width.ToString(new CultureInfo("en-US", false).NumberFormat), dimensionName));
                            writer.WriteElementString("g", "shipping_height", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", height.ToString(new CultureInfo("en-US", false).NumberFormat), dimensionName));
                        }

                        #endregion

                        writer.WriteEndElement(); // item
                    }
                }

                writer.WriteEndElement(); // channel
                writer.WriteEndElement(); // rss
                writer.WriteEndDocument();
            }
        }
Пример #4
0
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="customer">Load records allowed only to a specified customer; pass null to ignore ACL permissions</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList <ShoppingCartItem> cart,
                                                                    Address shippingAddress, Customer customer = null, string allowedShippingRateComputationMethodSystemName = "",
                                                                    int storeId = 0)
        {
            if (cart == null)
            {
                throw new ArgumentNullException(nameof(cart));
            }

            var result = new GetShippingOptionResponse();

            //create a package
            var shippingOptionRequests = CreateShippingOptionRequests(cart, shippingAddress, storeId, out var shippingFromMultipleLocations);

            result.ShippingFromMultipleLocations = shippingFromMultipleLocations;

            var shippingRateComputationMethods = _shippingPluginManager
                                                 .LoadActivePlugins(customer, storeId, allowedShippingRateComputationMethodSystemName);

            if (!shippingRateComputationMethods.Any())
            {
                return(result);
            }

            //request shipping options from each shipping rate computation methods
            foreach (var srcm in shippingRateComputationMethods)
            {
                //request shipping options (separately for each package-request)
                IList <ShippingOption> srcmShippingOptions = null;
                foreach (var shippingOptionRequest in shippingOptionRequests)
                {
                    var getShippingOptionResponse = srcm.GetShippingOptions(shippingOptionRequest);

                    if (getShippingOptionResponse.Success)
                    {
                        //success
                        if (srcmShippingOptions == null)
                        {
                            //first shipping option request
                            srcmShippingOptions = getShippingOptionResponse.ShippingOptions;
                        }
                        else
                        {
                            //get shipping options which already exist for prior requested packages for this scrm (i.e. common options)
                            srcmShippingOptions = srcmShippingOptions
                                                  .Where(existingso => getShippingOptionResponse.ShippingOptions.Any(newso => newso.Name == existingso.Name))
                                                  .ToList();

                            //and sum the rates
                            foreach (var existingso in srcmShippingOptions)
                            {
                                existingso.Rate += getShippingOptionResponse
                                                   .ShippingOptions
                                                   .First(newso => newso.Name == existingso.Name)
                                                   .Rate;
                            }
                        }
                    }
                    else
                    {
                        //errors
                        foreach (var error in getShippingOptionResponse.Errors)
                        {
                            result.AddError(error);
                            _logger.Warning($"Shipping ({srcm.PluginDescriptor.FriendlyName}). {error}");
                        }
                        //clear the shipping options in this case
                        srcmShippingOptions = new List <ShippingOption>();
                        break;
                    }
                }

                //add this scrm's options to the result
                if (srcmShippingOptions == null)
                {
                    continue;
                }

                foreach (var so in srcmShippingOptions)
                {
                    //set system name if not set yet
                    if (string.IsNullOrEmpty(so.ShippingRateComputationMethodSystemName))
                    {
                        so.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    }
                    if (_shoppingCartSettings.RoundPricesDuringCalculation)
                    {
                        so.Rate = _priceCalculationService.RoundPrice(so.Rate);
                    }
                    result.ShippingOptions.Add(so);
                }
            }

            if (_shippingSettings.ReturnValidOptionsIfThereAreAny)
            {
                //return valid options if there are any (no matter of the errors returned by other shipping rate computation methods).
                if (result.ShippingOptions.Any() && result.Errors.Any())
                {
                    result.Errors.Clear();
                }
            }

            //no shipping options loaded
            if (!result.ShippingOptions.Any() && !result.Errors.Any())
            {
                result.Errors.Add(_localizationService.GetResource("Checkout.ShippingOptionCouldNotBeLoaded"));
            }

            return(result);
        }
Пример #5
0
        /// <summary>
        /// Gets shopping cart total
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <param name="appliedGiftCards">Applied gift cards</param>
        /// <param name="discountAmount">Applied discount amount</param>
        /// <param name="appliedDiscounts">Applied discounts</param>
        /// <param name="redeemedRewardPoints">Reward points to redeem</param>
        /// <param name="redeemedRewardPointsAmount">Reward points amount in primary store currency to redeem</param>
        /// <param name="useRewardPoints">A value indicating reward points should be used; null to detect current choice of the customer</param>
        /// <param name="usePaymentMethodAdditionalFee">A value indicating whether we should use payment method additional fee when calculating order total</param>
        /// <returns>Shopping cart total;Null if shopping cart total couldn't be calculated now</returns>
        public override decimal?GetShoppingCartTotal(IList <ShoppingCartItem> cart,
                                                     out decimal discountAmount, out List <DiscountForCaching> appliedDiscounts,
                                                     out List <AppliedGiftCard> appliedGiftCards,
                                                     out int redeemedRewardPoints, out decimal redeemedRewardPointsAmount,
                                                     bool?useRewardPoints = null, bool usePaymentMethodAdditionalFee = true)
        {
            redeemedRewardPoints       = 0;
            redeemedRewardPointsAmount = decimal.Zero;

            var customer = cart.FirstOrDefault(item => item.Customer != null)?.Customer;
            var paymentMethodSystemName = string.Empty;

            if (customer != null)
            {
                paymentMethodSystemName = _genericAttributeService.GetAttribute <string>(customer,
                                                                                         NopCustomerDefaults.SelectedPaymentMethodAttribute, _storeContext.CurrentStore.Id);
            }

            //subtotal without tax
            GetShoppingCartSubTotal(cart, false, out _, out _, out _, out var subTotalWithDiscountBase);
            //subtotal with discount
            var subtotalBase = subTotalWithDiscountBase;

            //LoadAllShippingRateComputationMethods
            var shippingRateComputationMethods = _shippingPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id);

            //shipping without tax
            var shoppingCartShipping = GetShoppingCartShippingTotal(cart, false, shippingRateComputationMethods);

            //todo override this method again to include the refundable price
            //refundable price without tax
            var refundablePrice = cart.Sum(x => x.Product.RefundablePrice * x.Quantity);

            //payment method additional fee without tax
            var paymentMethodAdditionalFeeWithoutTax = decimal.Zero;

            if (usePaymentMethodAdditionalFee && !string.IsNullOrEmpty(paymentMethodSystemName))
            {
                var paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart,
                                                                                          paymentMethodSystemName);
                paymentMethodAdditionalFeeWithoutTax =
                    _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee,
                                                              false, customer);
            }

            //tax
            var shoppingCartTax = GetTaxTotal(cart, shippingRateComputationMethods, usePaymentMethodAdditionalFee);

            //Avalara plugin changes
            //adjust tax total according to received value from the Avalara
            shoppingCartTax = _httpContextAccessor.HttpContext.Session
                              .Get <TaxDetails>(AvalaraTaxDefaults.TaxDetailsSessionValue)?.TaxTotal ?? shoppingCartTax;
            //Avalara plugin changes

            //order total
            var resultTemp = decimal.Zero;

            //refundable price
            resultTemp += refundablePrice;

            resultTemp += subtotalBase;
            if (shoppingCartShipping.HasValue)
            {
                resultTemp += shoppingCartShipping.Value;
            }

            resultTemp += paymentMethodAdditionalFeeWithoutTax;
            resultTemp += shoppingCartTax;
            if (_shoppingCartSettings.RoundPricesDuringCalculation)
            {
                resultTemp = _priceCalculationService.RoundPrice(resultTemp);
            }

            //order total discount
            discountAmount = GetOrderTotalDiscount(customer, resultTemp, out appliedDiscounts);

            //sub totals with discount
            if (resultTemp < discountAmount)
            {
                discountAmount = resultTemp;
            }

            //reduce subtotal
            resultTemp -= discountAmount;

            if (resultTemp < decimal.Zero)
            {
                resultTemp = decimal.Zero;
            }
            if (_shoppingCartSettings.RoundPricesDuringCalculation)
            {
                resultTemp = _priceCalculationService.RoundPrice(resultTemp);
            }

            //let's apply gift cards now (gift cards that can be used)
            appliedGiftCards = new List <AppliedGiftCard>();
            AppliedGiftCards(cart, appliedGiftCards, customer, ref resultTemp);

            if (resultTemp < decimal.Zero)
            {
                resultTemp = decimal.Zero;
            }
            if (_shoppingCartSettings.RoundPricesDuringCalculation)
            {
                resultTemp = _priceCalculationService.RoundPrice(resultTemp);
            }

            if (!shoppingCartShipping.HasValue)
            {
                //we have errors
                return(null);
            }

            var orderTotal = resultTemp;

            //reward points
            SetRewardPoints(ref redeemedRewardPoints, ref redeemedRewardPointsAmount, useRewardPoints, customer, orderTotal);

            orderTotal = orderTotal - redeemedRewardPointsAmount;
            if (_shoppingCartSettings.RoundPricesDuringCalculation)
            {
                orderTotal = _priceCalculationService.RoundPrice(orderTotal);
            }

            //todo append the refundable price

            return(orderTotal);
        }